Commit 119c083e authored by Tobias Tebbi's avatar Tobias Tebbi Committed by Commit Bot

[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/1414911Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58880}
parent 02f23074
......@@ -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,12 +1421,12 @@ Node* CodeStubAssembler::StoreAndTagSmi(Node* base, int offset, Node* value) {
#endif
StoreNoWriteBarrier(MachineRepresentation::kWord32, base,
IntPtrConstant(zero_offset), Int32Constant(0));
return StoreNoWriteBarrier(MachineRepresentation::kWord32, base,
IntPtrConstant(payload_offset),
TruncateInt64ToInt32(value));
StoreNoWriteBarrier(MachineRepresentation::kWord32, base,
IntPtrConstant(payload_offset),
TruncateInt64ToInt32(value));
} else {
return StoreNoWriteBarrier(MachineRepresentation::kTaggedSigned, base,
IntPtrConstant(offset), SmiTag(value));
StoreNoWriteBarrier(MachineRepresentation::kTaggedSigned, base,
IntPtrConstant(offset), SmiTag(value));
}
}
......@@ -2673,58 +2673,59 @@ 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,
Node* value) {
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,
RootIndex map_root_index) {
return StoreMapNoWriteBarrier(object, LoadRoot(map_root_index));
void CodeStubAssembler::StoreMapNoWriteBarrier(Node* object,
RootIndex 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,
RootIndex root_index) {
void CodeStubAssembler::StoreObjectFieldRoot(Node* object, int offset,
RootIndex root_index) {
if (RootsTable::IsImmortalImmovable(root_index)) {
return StoreObjectFieldNoWriteBarrier(object, offset, LoadRoot(root_index));
} else {
......@@ -2732,14 +2733,14 @@ Node* CodeStubAssembler::StoreObjectFieldRoot(Node* object, int offset,
}
}
Node* CodeStubAssembler::StoreJSArrayLength(TNode<JSArray> array,
TNode<Smi> length) {
return StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length);
void CodeStubAssembler::StoreJSArrayLength(TNode<JSArray> array,
TNode<Smi> length) {
StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length);
}
Node* CodeStubAssembler::StoreElements(TNode<Object> object,
TNode<FixedArrayBase> elements) {
return StoreObjectField(object, JSObject::kElementsOffset, elements);
void CodeStubAssembler::StoreElements(TNode<Object> object,
TNode<FixedArrayBase> elements) {
StoreObjectField(object, JSObject::kElementsOffset, elements);
}
void CodeStubAssembler::StoreFixedArrayOrPropertyArrayElement(
......@@ -2800,12 +2801,12 @@ void CodeStubAssembler::StoreFixedDoubleArrayElement(
StoreNoWriteBarrier(rep, object, offset, value);
}
Node* CodeStubAssembler::StoreFeedbackVectorSlot(Node* object,
Node* slot_index_node,
Node* value,
WriteBarrierMode barrier_mode,
int additional_offset,
ParameterMode parameter_mode) {
void CodeStubAssembler::StoreFeedbackVectorSlot(Node* object,
Node* slot_index_node,
Node* value,
WriteBarrierMode barrier_mode,
int additional_offset,
ParameterMode parameter_mode) {
CSA_SLOW_ASSERT(this, IsFeedbackVector(object));
CSA_SLOW_ASSERT(this, MatchesParameterMode(slot_index_node, parameter_mode));
DCHECK(IsAligned(additional_offset, kTaggedSize));
......@@ -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,
WriteBarrierMode mode) {
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);
}
}
......
......@@ -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,8 +1312,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
Node* LoadCellValue(Node* cell);
Node* StoreCellValue(Node* cell, Node* value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
void StoreCellValue(Node* cell, Node* value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
// Allocate a HeapNumber without initializing its value.
TNode<HeapNumber> AllocateHeapNumber();
......
......@@ -975,15 +975,21 @@ Node* CodeAssembler::Store(Node* base, Node* value) {
kFullWriteBarrier);
}
Node* CodeAssembler::Store(Node* base, Node* offset, Node* value) {
return raw_assembler()->Store(MachineRepresentation::kTagged, base, offset,
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::StoreWithMapWriteBarrier(Node* base, Node* offset,
Node* value) {
Node* CodeAssembler::Store(Node* base, Node* offset, Node* value) {
return raw_assembler()->Store(MachineRepresentation::kTagged, base, offset,
value, kMapWriteBarrier);
value, kFullWriteBarrier);
}
Node* CodeAssembler::StoreNoWriteBarrier(MachineRepresentation rep, Node* base,
......
......@@ -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;
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment