[heap] Add a flag for disabling write barriers

The mode without write barriers works only if incremental marking
is disabled and the single generation mode is enabled.

Bug: v8:9533
Change-Id: Iecf83b0810f757c9b50e7fb338a2905af938f1d8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1716471
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63033}
This commit is contained in:
Rong Wang 2019-08-01 08:28:27 +10:00 committed by Commit Bot
parent 6d31360757
commit ae60ea7e7d
19 changed files with 98 additions and 24 deletions

View File

@ -188,8 +188,13 @@ declare_args() {
# Sets -DV8_SHARED_RO_HEAP.
v8_enable_shared_ro_heap = ""
# Redirect allocation in young generation so that there will be only one single generation.
v8_enable_single_generation = false
# Disable write barriers when GCs are non-incremental and
# heap has single generation.
v8_disable_write_barriers = false
# Redirect allocation in young generation so that there will be
# only one single generation.
v8_enable_single_generation = ""
}
# Derived defaults.
@ -225,6 +230,13 @@ if (v8_enable_fast_torque == "") {
v8_enable_fast_torque = v8_enable_fast_mksnapshot
}
if (v8_enable_single_generation == "") {
v8_enable_single_generation = v8_disable_write_barriers
}
assert(!v8_disable_write_barriers || v8_enable_single_generation,
"Disabling write barriers works only with single generation")
assert(v8_current_cpu != "x86" || !v8_untrusted_code_mitigations,
"Untrusted code mitigations are unsupported on ia32")
@ -421,6 +433,9 @@ config("features") {
if (v8_enable_single_generation) {
defines += [ "V8_ENABLE_SINGLE_GENERATION" ]
}
if (v8_disable_write_barriers) {
defines += [ "V8_DISABLE_WRITE_BARRIERS" ]
}
if (v8_use_external_startup_data) {
defines += [ "V8_USE_EXTERNAL_STARTUP_DATA" ]
}

View File

@ -801,8 +801,9 @@ void MacroAssembler::RecordWrite(Register object, Operand offset,
Check(eq, AbortReason::kWrongAddressOrValuePassedToRecordWrite);
}
if (remembered_set_action == OMIT_REMEMBERED_SET &&
!FLAG_incremental_marking) {
if ((remembered_set_action == OMIT_REMEMBERED_SET &&
!FLAG_incremental_marking) ||
FLAG_disable_write_barriers) {
return;
}

View File

@ -3014,6 +3014,12 @@ void MacroAssembler::RecordWrite(Register object, Operand offset,
Check(eq, AbortReason::kWrongAddressOrValuePassedToRecordWrite);
}
if ((remembered_set_action == OMIT_REMEMBERED_SET &&
!FLAG_incremental_marking) ||
FLAG_disable_write_barriers) {
return;
}
// First, check if a write barrier is even needed. The tests below
// catch stores of smis and stores into the young generation.
Label done;

View File

@ -465,8 +465,9 @@ void MacroAssembler::RecordWrite(Register object, Register address,
DCHECK(value != address);
AssertNotSmi(object);
if (remembered_set_action == OMIT_REMEMBERED_SET &&
!FLAG_incremental_marking) {
if ((remembered_set_action == OMIT_REMEMBERED_SET &&
!FLAG_incremental_marking) ||
FLAG_disable_write_barriers) {
return;
}

View File

@ -330,8 +330,9 @@ void MacroAssembler::RecordWrite(Register object, Register address,
Operand(value));
}
if (remembered_set_action == OMIT_REMEMBERED_SET &&
!FLAG_incremental_marking) {
if ((remembered_set_action == OMIT_REMEMBERED_SET &&
!FLAG_incremental_marking) ||
FLAG_disable_write_barriers) {
return;
}

View File

@ -328,8 +328,9 @@ void MacroAssembler::RecordWrite(Register object, Register address,
Operand(value));
}
if (remembered_set_action == OMIT_REMEMBERED_SET &&
!FLAG_incremental_marking) {
if ((remembered_set_action == OMIT_REMEMBERED_SET &&
!FLAG_incremental_marking) ||
FLAG_disable_write_barriers) {
return;
}

View File

@ -558,8 +558,9 @@ void MacroAssembler::RecordWrite(Register object, Register address,
Check(eq, AbortReason::kWrongAddressOrValuePassedToRecordWrite);
}
if (remembered_set_action == OMIT_REMEMBERED_SET &&
!FLAG_incremental_marking) {
if ((remembered_set_action == OMIT_REMEMBERED_SET &&
!FLAG_incremental_marking) ||
FLAG_disable_write_barriers) {
return;
}

View File

@ -576,8 +576,9 @@ void MacroAssembler::RecordWrite(Register object, Register address,
Check(eq, AbortReason::kWrongAddressOrValuePassedToRecordWrite);
}
if (remembered_set_action == OMIT_REMEMBERED_SET &&
!FLAG_incremental_marking) {
if ((remembered_set_action == OMIT_REMEMBERED_SET &&
!FLAG_incremental_marking) ||
FLAG_disable_write_barriers) {
return;
}
// First, check if a write barrier is even needed. The tests below

View File

@ -505,8 +505,9 @@ void MacroAssembler::RecordWrite(Register object, Register address,
DCHECK(value != address);
AssertNotSmi(object);
if (remembered_set_action == OMIT_REMEMBERED_SET &&
!FLAG_incremental_marking) {
if ((remembered_set_action == OMIT_REMEMBERED_SET &&
!FLAG_incremental_marking) ||
FLAG_disable_write_barriers) {
return;
}

View File

@ -518,7 +518,8 @@ void InstructionSelector::VisitStore(Node* node) {
WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind();
MachineRepresentation rep = store_rep.representation();
if (write_barrier_kind != kNoWriteBarrier) {
if (write_barrier_kind != kNoWriteBarrier &&
V8_LIKELY(!FLAG_disable_write_barriers)) {
DCHECK(CanBeTaggedPointer(rep));
AddressingMode addressing_mode;
InstructionOperand inputs[3];

View File

@ -679,7 +679,8 @@ void InstructionSelector::VisitStore(Node* node) {
MachineRepresentation rep = store_rep.representation();
// TODO(arm64): I guess this could be done in a better way.
if (write_barrier_kind != kNoWriteBarrier) {
if (write_barrier_kind != kNoWriteBarrier &&
V8_LIKELY(!FLAG_disable_write_barriers)) {
DCHECK(CanBeTaggedOrCompressedPointer(rep));
AddressingMode addressing_mode;
InstructionOperand inputs[3];

View File

@ -369,7 +369,8 @@ void InstructionSelector::VisitStore(Node* node) {
WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind();
MachineRepresentation rep = store_rep.representation();
if (write_barrier_kind != kNoWriteBarrier) {
if (write_barrier_kind != kNoWriteBarrier &&
V8_LIKELY(!FLAG_disable_write_barriers)) {
DCHECK(CanBeTaggedPointer(rep));
AddressingMode addressing_mode;
InstructionOperand inputs[] = {

View File

@ -352,7 +352,8 @@ void InstructionSelector::VisitStore(Node* node) {
MachineRepresentation rep = store_rep.representation();
// TODO(mips): I guess this could be done in a better way.
if (write_barrier_kind != kNoWriteBarrier) {
if (write_barrier_kind != kNoWriteBarrier &&
V8_LIKELY(!FLAG_disable_write_barriers)) {
DCHECK(CanBeTaggedPointer(rep));
InstructionOperand inputs[3];
size_t input_count = 0;

View File

@ -422,7 +422,8 @@ void InstructionSelector::VisitStore(Node* node) {
MachineRepresentation rep = store_rep.representation();
// TODO(mips): I guess this could be done in a better way.
if (write_barrier_kind != kNoWriteBarrier) {
if (write_barrier_kind != kNoWriteBarrier &&
V8_LIKELY(!FLAG_disable_write_barriers)) {
DCHECK(CanBeTaggedPointer(rep));
InstructionOperand inputs[3];
size_t input_count = 0;

View File

@ -267,7 +267,8 @@ void InstructionSelector::VisitStore(Node* node) {
rep = store_rep.representation();
}
if (write_barrier_kind != kNoWriteBarrier) {
if (write_barrier_kind != kNoWriteBarrier &&
V8_LIKELY(!FLAG_disable_write_barriers)) {
DCHECK(CanBeTaggedPointer(rep));
AddressingMode addressing_mode;
InstructionOperand inputs[3];

View File

@ -820,7 +820,9 @@ static void VisitGeneralStore(
void InstructionSelector::VisitStore(Node* node) {
StoreRepresentation store_rep = StoreRepresentationOf(node->op());
WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind();
WriteBarrierKind write_barrier_kind = V8_LIKELY(!FLAG_disable_write_barriers)
? store_rep.write_barrier_kind()
: kNoWriteBarrier;
MachineRepresentation rep = store_rep.representation();
VisitGeneralStore(this, node, rep, write_barrier_kind);

View File

@ -350,7 +350,8 @@ void InstructionSelector::VisitStore(Node* node) {
StoreRepresentation store_rep = StoreRepresentationOf(node->op());
WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind();
if (write_barrier_kind != kNoWriteBarrier) {
if (write_barrier_kind != kNoWriteBarrier &&
V8_LIKELY(!FLAG_disable_write_barriers)) {
DCHECK(CanBeTaggedOrCompressedPointer(store_rep.representation()));
AddressingMode addressing_mode;
InstructionOperand inputs[] = {

View File

@ -306,6 +306,19 @@ DEFINE_IMPLICATION(lite_mode, lazy_feedback_allocation)
DEFINE_IMPLICATION(lite_mode, enable_lazy_source_positions)
DEFINE_IMPLICATION(lite_mode, optimize_for_size)
#ifdef V8_DISABLE_WRITE_BARRIERS
#define V8_DISABLE_WRITE_BARRIERS_BOOL true
#else
#define V8_DISABLE_WRITE_BARRIERS_BOOL false
#endif
DEFINE_BOOL_READONLY(disable_write_barriers, V8_DISABLE_WRITE_BARRIERS_BOOL,
"disable write barriers when GC is non-incremental "
"and heap contains single generation.")
// Disable incremental marking barriers
DEFINE_NEG_IMPLICATION(disable_write_barriers, incremental_marking)
#ifdef V8_ENABLE_SINGLE_GENERATION
#define V8_GENERATION_BOOL true
#else

View File

@ -290,20 +290,31 @@
#define RELAXED_WRITE_WEAK_FIELD(p, offset, value) \
TaggedField<MaybeObject>::Relaxed_Store(p, offset, value)
#ifdef V8_DISABLE_WRITE_BARRIERS
#define WRITE_BARRIER(object, offset, value)
#else
#define WRITE_BARRIER(object, offset, value) \
do { \
DCHECK_NOT_NULL(GetHeapFromWritableObject(object)); \
MarkingBarrier(object, (object).RawField(offset), value); \
GenerationalBarrier(object, (object).RawField(offset), value); \
} while (false)
#endif
#ifdef V8_DISABLE_WRITE_BARRIERS
#define WEAK_WRITE_BARRIER(object, offset, value)
#else
#define WEAK_WRITE_BARRIER(object, offset, value) \
do { \
DCHECK_NOT_NULL(GetHeapFromWritableObject(object)); \
MarkingBarrier(object, (object).RawMaybeWeakField(offset), value); \
GenerationalBarrier(object, (object).RawMaybeWeakField(offset), value); \
} while (false)
#endif
#ifdef V8_DISABLE_WRITE_BARRIERS
#define EPHEMERON_KEY_WRITE_BARRIER(object, offset, value)
#else
#define EPHEMERON_KEY_WRITE_BARRIER(object, offset, value) \
do { \
DCHECK_NOT_NULL(GetHeapFromWritableObject(object)); \
@ -311,7 +322,11 @@
MarkingBarrier(object, (object).RawField(offset), value); \
GenerationalEphemeronKeyBarrier(table, (object).RawField(offset), value); \
} while (false)
#endif
#ifdef V8_DISABLE_WRITE_BARRIERS
#define CONDITIONAL_WRITE_BARRIER(object, offset, value, mode)
#else
#define CONDITIONAL_WRITE_BARRIER(object, offset, value, mode) \
do { \
DCHECK_NOT_NULL(GetHeapFromWritableObject(object)); \
@ -323,7 +338,11 @@
GenerationalBarrier(object, (object).RawField(offset), value); \
} \
} while (false)
#endif
#ifdef V8_DISABLE_WRITE_BARRIERS
#define CONDITIONAL_WEAK_WRITE_BARRIER(object, offset, value, mode)
#else
#define CONDITIONAL_WEAK_WRITE_BARRIER(object, offset, value, mode) \
do { \
DCHECK_NOT_NULL(GetHeapFromWritableObject(object)); \
@ -335,7 +354,11 @@
GenerationalBarrier(object, (object).RawMaybeWeakField(offset), value); \
} \
} while (false)
#endif
#ifdef V8_DISABLE_WRITE_BARRIERS
#define CONDITIONAL_EPHEMERON_KEY_WRITE_BARRIER(object, offset, value, mode)
#else
#define CONDITIONAL_EPHEMERON_KEY_WRITE_BARRIER(object, offset, value, mode) \
do { \
DCHECK_NOT_NULL(GetHeapFromWritableObject(object)); \
@ -349,6 +372,7 @@
value); \
} \
} while (false)
#endif
#define ACQUIRE_READ_INT32_FIELD(p, offset) \
static_cast<int32_t>(base::Acquire_Load( \