[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:
parent
6d31360757
commit
ae60ea7e7d
19
BUILD.gn
19
BUILD.gn
@ -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" ]
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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];
|
||||
|
@ -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];
|
||||
|
@ -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[] = {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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];
|
||||
|
@ -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);
|
||||
|
@ -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[] = {
|
||||
|
@ -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
|
||||
|
@ -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( \
|
||||
|
Loading…
Reference in New Issue
Block a user