Reviewers: Lasse Reichstein,

Description:
Patch RecordWriteStub after adding it to the stub cache not during generation.

This guarantees that stub's mode will match the state of incremental marker.

[email protected]
BUG=v8:1545


Please review this at http://codereview.chromium.org/7329049/

SVN Base: https://v8.googlecode.com/svn/branches/experimental/gc

Affected files:
  M src/arm/code-stubs-arm.h
  M src/code-stubs.cc
  M src/ia32/code-stubs-ia32.cc
  M src/incremental-marking.h
  M src/incremental-marking.cc
  M src/x64/code-stubs-x64.cc


Index: src/arm/code-stubs-arm.h
diff --git a/src/arm/code-stubs-arm.h b/src/arm/code-stubs-arm.h
index b2306b52c80e5feb0d62adabb5d840519a0a793f..77be7e1163593815e8a0e166adcd1a2c84f8d1e3 100644
--- a/src/arm/code-stubs-arm.h
+++ b/src/arm/code-stubs-arm.h
@@ -466,6 +466,10 @@ class RecordWriteStub: public CodeStub {
     INCREMENTAL_COMPACTION
   };

+  static Mode GetMode(Code* stub) {
+    return STORE_BUFFER_ONLY;
+  }
+
   static void Patch(Code* stub, Mode mode) {
     ASSERT(mode == STORE_BUFFER_ONLY);
   }
Index: src/code-stubs.cc
diff --git a/src/code-stubs.cc b/src/code-stubs.cc
index d12def85efa03dd539341af65f32bec7349e2984..da5d97890c36eb931c1ac0237dd3f750cb9663da 100644
--- a/src/code-stubs.cc
+++ b/src/code-stubs.cc
@@ -120,8 +120,10 @@ Handle<Code> CodeStub::GetCode() {
             GetKey(),
             new_object);
     heap->public_set_code_stubs(*dict);
-
     code = *new_object;
+    if (MajorKey() == RecordWrite) {
+      heap->incremental_marking()->ActivateGeneratedStub(code);
+    }
   }

   ASSERT(!NeedsImmovableCode() || heap->lo_space()->Contains(code));
@@ -160,6 +162,14 @@ MaybeObject* CodeStub::TryGetCode() {
         heap->code_stubs()->AtNumberPut(GetKey(), code);
     if (maybe_new_object->ToObject(&new_object)) {
       heap->public_set_code_stubs(NumberDictionary::cast(new_object));
+    } else if (MajorKey() == RecordWrite) {
+      // All RecordWrite stubs have to be registered in the stub cache.
+      return maybe_new_object;
+    }
+
+ // If this is a RecordWrite stub we need to patch it to ensure correct state.
+    if (MajorKey() == RecordWrite) {
+      heap->incremental_marking()->ActivateGeneratedStub(code);
     }
   }

Index: src/ia32/code-stubs-ia32.cc
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index 5b88a85a2ce51594d25b44d34182ad032b01b41b..e4889ba7feb8c49885018aaf0ca688436d193aba 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -6258,18 +6258,10 @@ void RecordWriteStub::Generate(MacroAssembler* masm) {
   __ bind(&skip_to_incremental_compacting);
   GenerateIncremental(masm, INCREMENTAL_COMPACTION);

- // TODO(1545) ensure that GC can't happen after stub was generated by before
-  // it was added to a stub cache.
- IncrementalMarking* marking = masm->isolate()->heap()->incremental_marking();
-  if (!marking->IsMarking() || marking->IsCompacting()) {
-    ASSERT(masm->byte_at(0) == kTwoByteJumpInstruction);
-    masm->set_byte_at(0, kTwoByteNopInstruction);
-  }
-
-  if (!marking->IsMarking()) {
-    ASSERT(masm->byte_at(2) == kFiveByteJumpInstruction);
-    masm->set_byte_at(2, kFiveByteNopInstruction);
-  }
+  // Initial mode of the stub is expected to be STORE_BUFFER_ONLY.
+  // Will be checked in IncrementalMarking::ActivateGeneratedStub.
+  masm->set_byte_at(0, kTwoByteNopInstruction);
+  masm->set_byte_at(2, kFiveByteNopInstruction);
 }


Index: src/incremental-marking.cc
diff --git a/src/incremental-marking.cc b/src/incremental-marking.cc
index 0e53a380ac717a7741ddf172327a821dc0631d94..b34f50c8fed139988af21428e87751b03c0dd2b2 100644
--- a/src/incremental-marking.cc
+++ b/src/incremental-marking.cc
@@ -305,6 +305,22 @@ bool IncrementalMarking::WorthActivating() {
 }


+void IncrementalMarking::ActivateGeneratedStub(Code* stub) {
+  ASSERT(RecordWriteStub::GetMode(stub) ==
+             RecordWriteStub::STORE_BUFFER_ONLY);
+
+  if (!IsMarking()) {
+    // Initially stub is generated in STORE_BUFFER_ONLY mode thus
+    // we don't need to do anything if incremental marking is
+    // not active.
+  } else if (IsCompacting()) {
+    RecordWriteStub::Patch(stub, RecordWriteStub::INCREMENTAL_COMPACTION);
+  } else {
+    RecordWriteStub::Patch(stub, RecordWriteStub::INCREMENTAL);
+  }
+}
+
+
 static void PatchIncrementalMarkingRecordWriteStubs(
     Heap* heap, RecordWriteStub::Mode mode) {
   NumberDictionary* stubs = heap->code_stubs();
Index: src/incremental-marking.h
diff --git a/src/incremental-marking.h b/src/incremental-marking.h
index a97ba793176516517255e30417f2c22a126117d3..2e0886ae2c04ce4d49e29420c78b9dc8e8bc5f37 100644
--- a/src/incremental-marking.h
+++ b/src/incremental-marking.h
@@ -162,6 +162,8 @@ class IncrementalMarking {

   bool IsCompacting() { return IsMarking() && is_compacting_; }

+  void ActivateGeneratedStub(Code* stub);
+
  private:
   void set_should_hurry(bool val) {
     should_hurry_ = val;
Index: src/x64/code-stubs-x64.cc
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index 9432304a5af6c338e43aad9c7f38c856c6e092b7..bb365c880d291b2f220f7620740ced780acfcade 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -5182,18 +5182,10 @@ void RecordWriteStub::Generate(MacroAssembler* masm) {
   __ bind(&skip_to_incremental_compacting);
   GenerateIncremental(masm, INCREMENTAL_COMPACTION);

- // TODO(1545) ensure that GC can't happen after stub was generated by before
-  // it was added to a stub cache.
- IncrementalMarking* marking = masm->isolate()->heap()->incremental_marking();
-  if (!marking->IsMarking() || marking->IsCompacting()) {
-    ASSERT(masm->byte_at(0) == kTwoByteJumpInstruction);
-    masm->set_byte_at(0, kTwoByteNopInstruction);
-  }
-
-  if (!marking->IsMarking()) {
-    ASSERT(masm->byte_at(2) == kFiveByteJumpInstruction);
-    masm->set_byte_at(2, kFiveByteNopInstruction);
-  }
+  // Initial mode of the stub is expected to be STORE_BUFFER_ONLY.
+  // Will be checked in IncrementalMarking::ActivateGeneratedStub.
+  masm->set_byte_at(0, kTwoByteNopInstruction);
+  masm->set_byte_at(2, kFiveByteNopInstruction);
 }




--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to