| Index: src/compiler/simplified-lowering.cc
|
| diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc
|
| index aceecab39a1710cfa523ef3af6b5e295b5ae84a4..af2f2518fa5dddd5fa33f8969bbe4ea0c5b0afed 100644
|
| --- a/src/compiler/simplified-lowering.cc
|
| +++ b/src/compiler/simplified-lowering.cc
|
| @@ -6,6 +6,7 @@
|
|
|
| #include <limits>
|
|
|
| +#include "src/address-map.h"
|
| #include "src/base/bits.h"
|
| #include "src/code-factory.h"
|
| #include "src/compiler/access-builder.h"
|
| @@ -18,6 +19,7 @@
|
| #include "src/compiler/representation-change.h"
|
| #include "src/compiler/simplified-operator.h"
|
| #include "src/compiler/source-position.h"
|
| +#include "src/conversions-inl.h"
|
| #include "src/objects.h"
|
| #include "src/type-cache.h"
|
|
|
| @@ -709,6 +711,71 @@
|
| return changer_->Float64OperatorFor(node->opcode());
|
| }
|
|
|
| + WriteBarrierKind WriteBarrierKindFor(
|
| + BaseTaggedness base_taggedness,
|
| + MachineRepresentation field_representation, Type* field_type,
|
| + Node* value) {
|
| + if (base_taggedness == kTaggedBase &&
|
| + field_representation == MachineRepresentation::kTagged) {
|
| + Type* value_type = NodeProperties::GetType(value);
|
| + if (field_type->Is(Type::TaggedSigned()) ||
|
| + value_type->Is(Type::TaggedSigned())) {
|
| + // Write barriers are only for stores of heap objects.
|
| + return kNoWriteBarrier;
|
| + }
|
| + if (field_type->Is(Type::BooleanOrNullOrUndefined()) ||
|
| + value_type->Is(Type::BooleanOrNullOrUndefined())) {
|
| + // Write barriers are not necessary when storing true, false, null or
|
| + // undefined, because these special oddballs are always in the root set.
|
| + return kNoWriteBarrier;
|
| + }
|
| + if (value_type->IsConstant() &&
|
| + value_type->AsConstant()->Value()->IsHeapObject()) {
|
| + Handle<HeapObject> value_object =
|
| + Handle<HeapObject>::cast(value_type->AsConstant()->Value());
|
| + if (value_object->IsMap()) {
|
| + // Write barriers for storing maps are cheaper.
|
| + return kMapWriteBarrier;
|
| + }
|
| + RootIndexMap root_index_map(jsgraph_->isolate());
|
| + int root_index = root_index_map.Lookup(*value_object);
|
| + if (root_index != RootIndexMap::kInvalidRootIndex &&
|
| + jsgraph_->isolate()->heap()->RootIsImmortalImmovable(root_index)) {
|
| + // Write barriers are unnecessary for immortal immovable roots.
|
| + return kNoWriteBarrier;
|
| + }
|
| + }
|
| + if (field_type->Is(Type::TaggedPointer()) ||
|
| + value_type->Is(Type::TaggedPointer())) {
|
| + // Write barriers for heap objects are cheaper.
|
| + return kPointerWriteBarrier;
|
| + }
|
| + NumberMatcher m(value);
|
| + if (m.HasValue()) {
|
| + if (IsSmiDouble(m.Value())) {
|
| + // Storing a smi doesn't need a write barrier.
|
| + return kNoWriteBarrier;
|
| + }
|
| + // The NumberConstant will be represented as HeapNumber.
|
| + return kPointerWriteBarrier;
|
| + }
|
| + return kFullWriteBarrier;
|
| + }
|
| + return kNoWriteBarrier;
|
| + }
|
| +
|
| + WriteBarrierKind WriteBarrierKindFor(
|
| + BaseTaggedness base_taggedness,
|
| + MachineRepresentation field_representation, int field_offset,
|
| + Type* field_type, Node* value) {
|
| + if (base_taggedness == kTaggedBase &&
|
| + field_offset == HeapObject::kMapOffset) {
|
| + return kMapWriteBarrier;
|
| + }
|
| + return WriteBarrierKindFor(base_taggedness, field_representation,
|
| + field_type, value);
|
| + }
|
| +
|
| // Dispatching routine for visiting the node {node} with the usage {use}.
|
| // Depending on the operator, propagate new usage info to the inputs.
|
| void VisitNode(Node* node, Truncation truncation,
|
| @@ -1136,6 +1203,16 @@
|
| access.machine_type.representation()));
|
| ProcessRemainingInputs(node, 2);
|
| SetOutput(node, MachineRepresentation::kNone);
|
| + if (lower()) {
|
| + WriteBarrierKind write_barrier_kind = WriteBarrierKindFor(
|
| + access.base_is_tagged, access.machine_type.representation(),
|
| + access.offset, access.type, node->InputAt(1));
|
| + if (write_barrier_kind < access.write_barrier_kind) {
|
| + access.write_barrier_kind = write_barrier_kind;
|
| + NodeProperties::ChangeOp(
|
| + node, jsgraph_->simplified()->StoreField(access));
|
| + }
|
| + }
|
| break;
|
| }
|
| case IrOpcode::kLoadBuffer: {
|
| @@ -1201,6 +1278,16 @@
|
| access.machine_type.representation())); // value
|
| ProcessRemainingInputs(node, 3);
|
| SetOutput(node, MachineRepresentation::kNone);
|
| + if (lower()) {
|
| + WriteBarrierKind write_barrier_kind = WriteBarrierKindFor(
|
| + access.base_is_tagged, access.machine_type.representation(),
|
| + access.type, node->InputAt(2));
|
| + if (write_barrier_kind < access.write_barrier_kind) {
|
| + access.write_barrier_kind = write_barrier_kind;
|
| + NodeProperties::ChangeOp(
|
| + node, jsgraph_->simplified()->StoreElement(access));
|
| + }
|
| + }
|
| break;
|
| }
|
| case IrOpcode::kObjectIsCallable:
|
|
|