[csa] emit Turbofan's StoreField nodes to eliminate write barriers

This triggers the optimizing StoreField lowering in the MemoryOptimizer.

Drive-by cleanup: Remove useless return values in CSA store functions.

Bug: v8:7793
Change-Id: I08417a81ca321dcd27ff5cc3a11ef74262d419fb
Reviewed-on: https://chromium-review.googlesource.com/c/1414911
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58880}
This commit is contained in:
Tobias Tebbi 2019-01-16 15:30:40 +01:00 committed by Commit Bot
parent 02f230740c
commit 119c083e05
5 changed files with 105 additions and 85 deletions

View File

@ -1412,7 +1412,7 @@ TNode<Int32T> CodeStubAssembler::LoadAndUntagToWord32Root(
}
}
Node* CodeStubAssembler::StoreAndTagSmi(Node* base, int offset, Node* value) {
void CodeStubAssembler::StoreAndTagSmi(Node* base, int offset, Node* value) {
if (SmiValuesAre32Bits()) {
int zero_offset = offset + 4;
int payload_offset = offset;
@ -1421,11 +1421,11 @@ Node* CodeStubAssembler::StoreAndTagSmi(Node* base, int offset, Node* value) {
#endif
StoreNoWriteBarrier(MachineRepresentation::kWord32, base,
IntPtrConstant(zero_offset), Int32Constant(0));
return StoreNoWriteBarrier(MachineRepresentation::kWord32, base,
StoreNoWriteBarrier(MachineRepresentation::kWord32, base,
IntPtrConstant(payload_offset),
TruncateInt64ToInt32(value));
} else {
return StoreNoWriteBarrier(MachineRepresentation::kTaggedSigned, base,
StoreNoWriteBarrier(MachineRepresentation::kTaggedSigned, base,
IntPtrConstant(offset), SmiTag(value));
}
}
@ -2673,57 +2673,58 @@ void CodeStubAssembler::StoreMutableHeapNumberValue(
MachineRepresentation::kFloat64);
}
Node* CodeStubAssembler::StoreObjectField(
Node* object, int offset, Node* value) {
void CodeStubAssembler::StoreObjectField(Node* object, int offset,
Node* value) {
DCHECK_NE(HeapObject::kMapOffset, offset); // Use StoreMap instead.
return Store(object, IntPtrConstant(offset - kHeapObjectTag), value);
OptimizedStoreField(MachineRepresentation::kTagged,
UncheckedCast<HeapObject>(object), offset, value,
WriteBarrierKind::kFullWriteBarrier);
}
Node* CodeStubAssembler::StoreObjectField(Node* object, Node* offset,
void CodeStubAssembler::StoreObjectField(Node* object, Node* offset,
Node* value) {
int const_offset;
if (ToInt32Constant(offset, const_offset)) {
return StoreObjectField(object, const_offset, value);
StoreObjectField(object, const_offset, value);
} else {
Store(object, IntPtrSub(offset, IntPtrConstant(kHeapObjectTag)), value);
}
return Store(object, IntPtrSub(offset, IntPtrConstant(kHeapObjectTag)),
value);
}
Node* CodeStubAssembler::StoreObjectFieldNoWriteBarrier(
void CodeStubAssembler::StoreObjectFieldNoWriteBarrier(
Node* object, int offset, Node* value, MachineRepresentation rep) {
return StoreNoWriteBarrier(rep, object,
IntPtrConstant(offset - kHeapObjectTag), value);
OptimizedStoreField(rep, UncheckedCast<HeapObject>(object), offset, value,
WriteBarrierKind::kNoWriteBarrier);
}
Node* CodeStubAssembler::StoreObjectFieldNoWriteBarrier(
void CodeStubAssembler::StoreObjectFieldNoWriteBarrier(
Node* object, Node* offset, Node* value, MachineRepresentation rep) {
int const_offset;
if (ToInt32Constant(offset, const_offset)) {
return StoreObjectFieldNoWriteBarrier(object, const_offset, value, rep);
}
return StoreNoWriteBarrier(
rep, object, IntPtrSub(offset, IntPtrConstant(kHeapObjectTag)), value);
StoreNoWriteBarrier(rep, object,
IntPtrSub(offset, IntPtrConstant(kHeapObjectTag)), value);
}
Node* CodeStubAssembler::StoreMap(Node* object, Node* map) {
CSA_SLOW_ASSERT(this, IsMap(map));
return StoreWithMapWriteBarrier(
object, IntPtrConstant(HeapObject::kMapOffset - kHeapObjectTag), map);
void CodeStubAssembler::StoreMap(Node* object, Node* map) {
OptimizedStoreMap(UncheckedCast<HeapObject>(object), CAST(map));
}
Node* CodeStubAssembler::StoreMapNoWriteBarrier(Node* object,
void CodeStubAssembler::StoreMapNoWriteBarrier(Node* object,
RootIndex map_root_index) {
return StoreMapNoWriteBarrier(object, LoadRoot(map_root_index));
StoreMapNoWriteBarrier(object, LoadRoot(map_root_index));
}
Node* CodeStubAssembler::StoreMapNoWriteBarrier(Node* object, Node* map) {
void CodeStubAssembler::StoreMapNoWriteBarrier(Node* object, Node* map) {
CSA_SLOW_ASSERT(this, IsMap(map));
return StoreNoWriteBarrier(
MachineRepresentation::kTagged, object,
IntPtrConstant(HeapObject::kMapOffset - kHeapObjectTag), map);
OptimizedStoreField(MachineRepresentation::kTaggedPointer,
UncheckedCast<HeapObject>(object), HeapObject::kMapOffset,
map, WriteBarrierKind::kNoWriteBarrier);
}
Node* CodeStubAssembler::StoreObjectFieldRoot(Node* object, int offset,
void CodeStubAssembler::StoreObjectFieldRoot(Node* object, int offset,
RootIndex root_index) {
if (RootsTable::IsImmortalImmovable(root_index)) {
return StoreObjectFieldNoWriteBarrier(object, offset, LoadRoot(root_index));
@ -2732,14 +2733,14 @@ Node* CodeStubAssembler::StoreObjectFieldRoot(Node* object, int offset,
}
}
Node* CodeStubAssembler::StoreJSArrayLength(TNode<JSArray> array,
void CodeStubAssembler::StoreJSArrayLength(TNode<JSArray> array,
TNode<Smi> length) {
return StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length);
StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length);
}
Node* CodeStubAssembler::StoreElements(TNode<Object> object,
void CodeStubAssembler::StoreElements(TNode<Object> object,
TNode<FixedArrayBase> elements) {
return StoreObjectField(object, JSObject::kElementsOffset, elements);
StoreObjectField(object, JSObject::kElementsOffset, elements);
}
void CodeStubAssembler::StoreFixedArrayOrPropertyArrayElement(
@ -2800,7 +2801,7 @@ void CodeStubAssembler::StoreFixedDoubleArrayElement(
StoreNoWriteBarrier(rep, object, offset, value);
}
Node* CodeStubAssembler::StoreFeedbackVectorSlot(Node* object,
void CodeStubAssembler::StoreFeedbackVectorSlot(Node* object,
Node* slot_index_node,
Node* value,
WriteBarrierMode barrier_mode,
@ -2820,10 +2821,9 @@ Node* CodeStubAssembler::StoreFeedbackVectorSlot(Node* object,
IsOffsetInBounds(offset, LoadFeedbackVectorLength(CAST(object)),
FeedbackVector::kHeaderSize));
if (barrier_mode == SKIP_WRITE_BARRIER) {
return StoreNoWriteBarrier(MachineRepresentation::kTagged, object, offset,
value);
StoreNoWriteBarrier(MachineRepresentation::kTagged, object, offset, value);
} else {
return Store(object, offset, value);
Store(object, offset, value);
}
}
@ -2993,15 +2993,15 @@ Node* CodeStubAssembler::LoadCellValue(Node* cell) {
return LoadObjectField(cell, Cell::kValueOffset);
}
Node* CodeStubAssembler::StoreCellValue(Node* cell, Node* value,
void CodeStubAssembler::StoreCellValue(Node* cell, Node* value,
WriteBarrierMode mode) {
CSA_SLOW_ASSERT(this, HasInstanceType(cell, CELL_TYPE));
DCHECK(mode == SKIP_WRITE_BARRIER || mode == UPDATE_WRITE_BARRIER);
if (mode == UPDATE_WRITE_BARRIER) {
return StoreObjectField(cell, Cell::kValueOffset, value);
StoreObjectField(cell, Cell::kValueOffset, value);
} else {
return StoreObjectFieldNoWriteBarrier(cell, Cell::kValueOffset, value);
StoreObjectFieldNoWriteBarrier(cell, Cell::kValueOffset, value);
}
}

View File

@ -824,7 +824,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
}
// Tag a smi and store it.
Node* StoreAndTagSmi(Node* base, int offset, Node* value);
void StoreAndTagSmi(Node* base, int offset, Node* value);
// Load the floating point value of a HeapNumber.
TNode<Float64T> LoadHeapNumberValue(SloppyTNode<HeapNumber> object);
@ -1185,28 +1185,27 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
void StoreMutableHeapNumberValue(SloppyTNode<MutableHeapNumber> object,
SloppyTNode<Float64T> value);
// Store a field to an object on the heap.
Node* StoreObjectField(Node* object, int offset, Node* value);
Node* StoreObjectField(Node* object, Node* offset, Node* value);
Node* StoreObjectFieldNoWriteBarrier(
void StoreObjectField(Node* object, int offset, Node* value);
void StoreObjectField(Node* object, Node* offset, Node* value);
void StoreObjectFieldNoWriteBarrier(
Node* object, int offset, Node* value,
MachineRepresentation rep = MachineRepresentation::kTagged);
Node* StoreObjectFieldNoWriteBarrier(
void StoreObjectFieldNoWriteBarrier(
Node* object, Node* offset, Node* value,
MachineRepresentation rep = MachineRepresentation::kTagged);
template <class T = Object>
TNode<T> StoreObjectFieldNoWriteBarrier(TNode<HeapObject> object,
TNode<IntPtrT> offset,
TNode<T> value) {
return UncheckedCast<T>(StoreObjectFieldNoWriteBarrier(
object, offset, value, MachineRepresentationOf<T>::value));
void StoreObjectFieldNoWriteBarrier(TNode<HeapObject> object,
TNode<IntPtrT> offset, TNode<T> value) {
StoreObjectFieldNoWriteBarrier(object, offset, value,
MachineRepresentationOf<T>::value);
}
// Store the Map of an HeapObject.
Node* StoreMap(Node* object, Node* map);
Node* StoreMapNoWriteBarrier(Node* object, RootIndex map_root_index);
Node* StoreMapNoWriteBarrier(Node* object, Node* map);
Node* StoreObjectFieldRoot(Node* object, int offset, RootIndex root);
void StoreMap(Node* object, Node* map);
void StoreMapNoWriteBarrier(Node* object, RootIndex map_root_index);
void StoreMapNoWriteBarrier(Node* object, Node* map);
void StoreObjectFieldRoot(Node* object, int offset, RootIndex root);
// Store an array element to a FixedArray.
void StoreFixedArrayElement(
TNode<FixedArray> object, int index, SloppyTNode<Object> value,
@ -1220,8 +1219,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
SKIP_WRITE_BARRIER);
}
Node* StoreJSArrayLength(TNode<JSArray> array, TNode<Smi> length);
Node* StoreElements(TNode<Object> object, TNode<FixedArrayBase> elements);
void StoreJSArrayLength(TNode<JSArray> array, TNode<Smi> length);
void StoreElements(TNode<Object> object, TNode<FixedArrayBase> elements);
void StoreFixedArrayOrPropertyArrayElement(
Node* array, Node* index, Node* value,
@ -1276,7 +1275,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
StoreFixedDoubleArrayHole(array, index, SMI_PARAMETERS);
}
Node* StoreFeedbackVectorSlot(
void StoreFeedbackVectorSlot(
Node* object, Node* index, Node* value,
WriteBarrierMode barrier_mode = UPDATE_WRITE_BARRIER,
int additional_offset = 0,
@ -1313,7 +1312,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
Node* LoadCellValue(Node* cell);
Node* StoreCellValue(Node* cell, Node* value,
void StoreCellValue(Node* cell, Node* value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
// Allocate a HeapNumber without initializing its value.

View File

@ -975,17 +975,23 @@ Node* CodeAssembler::Store(Node* base, Node* value) {
kFullWriteBarrier);
}
void CodeAssembler::OptimizedStoreField(MachineRepresentation rep,
TNode<HeapObject> object, int offset,
Node* value,
WriteBarrierKind write_barrier) {
raw_assembler()->OptimizedStoreField(rep, object, offset, value,
write_barrier);
}
void CodeAssembler::OptimizedStoreMap(TNode<HeapObject> object,
TNode<Map> map) {
raw_assembler()->OptimizedStoreMap(object, map);
}
Node* CodeAssembler::Store(Node* base, Node* offset, Node* value) {
return raw_assembler()->Store(MachineRepresentation::kTagged, base, offset,
value, kFullWriteBarrier);
}
Node* CodeAssembler::StoreWithMapWriteBarrier(Node* base, Node* offset,
Node* value) {
return raw_assembler()->Store(MachineRepresentation::kTagged, base, offset,
value, kMapWriteBarrier);
}
Node* CodeAssembler::StoreNoWriteBarrier(MachineRepresentation rep, Node* base,
Node* value) {
return raw_assembler()->Store(rep, base, value, kNoWriteBarrier);

View File

@ -920,10 +920,16 @@ class V8_EXPORT_PRIVATE CodeAssembler {
// Store value to raw memory location.
Node* Store(Node* base, Node* value);
Node* Store(Node* base, Node* offset, Node* value);
Node* StoreWithMapWriteBarrier(Node* base, Node* offset, Node* value);
Node* StoreNoWriteBarrier(MachineRepresentation rep, Node* base, Node* value);
Node* StoreNoWriteBarrier(MachineRepresentation rep, Node* base, Node* offset,
Node* value);
// Optimized memory operations that map to Turbofan simplified nodes.
TNode<HeapObject> OptimizedAllocate(TNode<IntPtrT> size,
PretenureFlag pretenure);
void OptimizedStoreField(MachineRepresentation rep, TNode<HeapObject> object,
int offset, Node* value,
WriteBarrierKind write_barrier);
void OptimizedStoreMap(TNode<HeapObject> object, TNode<Map>);
// {value_high} is used for 64-bit stores on 32-bit platforms, must be
// nullptr in other cases.
Node* AtomicStore(MachineRepresentation rep, Node* base, Node* offset,
@ -1342,9 +1348,6 @@ class V8_EXPORT_PRIVATE CodeAssembler {
void GotoIfException(Node* node, Label* if_exception,
Variable* exception_var = nullptr);
TNode<HeapObject> OptimizedAllocate(TNode<IntPtrT> size,
PretenureFlag pretenure);
// Helpers which delegate to RawMachineAssembler.
Factory* factory() const;
Isolate* isolate() const;

View File

@ -6,6 +6,7 @@
#define V8_COMPILER_RAW_MACHINE_ASSEMBLER_H_
#include "src/assembler.h"
#include "src/compiler/access-builder.h"
#include "src/compiler/common-operator.h"
#include "src/compiler/graph.h"
#include "src/compiler/linkage.h"
@ -145,6 +146,17 @@ class V8_EXPORT_PRIVATE RawMachineAssembler {
return AddNode(machine()->Store(StoreRepresentation(rep, write_barrier)),
base, index, value);
}
void OptimizedStoreField(MachineRepresentation rep, Node* object, int offset,
Node* value, WriteBarrierKind write_barrier) {
AddNode(simplified()->StoreField(FieldAccess(
BaseTaggedness::kTaggedBase, offset, MaybeHandle<Name>(),
MaybeHandle<Map>(), Type::Any(),
MachineType::TypeForRepresentation(rep), write_barrier)),
object, value);
}
void OptimizedStoreMap(Node* object, Node* value) {
AddNode(simplified()->StoreField(AccessBuilder::ForMap()), object, value);
}
Node* Retain(Node* value) { return AddNode(common()->Retain(), value); }
Node* OptimizedAllocate(Node* size, PretenureFlag pretenure);