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