diff options
author | Ali Ijaz Sheikh <ofrobots@google.com> | 2016-01-20 09:45:45 -0800 |
---|---|---|
committer | Ali Ijaz Sheikh <ofrobots@google.com> | 2016-01-21 16:53:58 -0800 |
commit | ef4170ea03a80b21b2d8a65ce432efaa370fe2fa (patch) | |
tree | e382b1b38b729cd8155b56b441c3a563914854a3 /deps/v8/src/compiler/simplified-lowering.cc | |
parent | 5f6dfab832979999d2f806fc1a2f1c11a25b0f35 (diff) | |
download | node-new-ef4170ea03a80b21b2d8a65ce432efaa370fe2fa.tar.gz |
deps: upgrade to V8 4.8.271.17
Pick up V8 4.8 branch-head. This branch brings in @@isConcatSpreadable,
@@toPrimitive and ToLength ES6 changes. For full details see:
http://v8project.blogspot.de/2015/11/v8-release-48.html
https://github.com/v8/v8/commit/fa163e2
Ref: https://github.com/nodejs/node/pull/4399
PR-URL: https://github.com/nodejs/node/pull/4785
Reviewed-By: bnoordhuis - Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'deps/v8/src/compiler/simplified-lowering.cc')
-rw-r--r-- | deps/v8/src/compiler/simplified-lowering.cc | 221 |
1 files changed, 126 insertions, 95 deletions
diff --git a/deps/v8/src/compiler/simplified-lowering.cc b/deps/v8/src/compiler/simplified-lowering.cc index 7d495bf983..80c7ff5a94 100644 --- a/deps/v8/src/compiler/simplified-lowering.cc +++ b/deps/v8/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/common-operator.h" @@ -331,9 +332,7 @@ class RepresentationSelector { if (upper->Is(Type::Signed32()) || upper->Is(Type::Unsigned32())) { // multiple uses, but we are within 32 bits range => pick kRepWord32. return kRepWord32; - } else if (((use & kRepMask) == kRepWord32 && - !CanObserveNonWord32(use)) || - (use & kTypeMask) == kTypeInt32 || + } else if ((use & kTypeMask) == kTypeInt32 || (use & kTypeMask) == kTypeUint32) { // We only use 32 bits or we use the result consistently. return kRepWord32; @@ -474,47 +473,29 @@ class RepresentationSelector { bool CanLowerToInt32Binop(Node* node, MachineTypeUnion use) { return BothInputsAre(node, Type::Signed32()) && - (!CanObserveNonInt32(use) || + (!CanObserveNonWord32(use) || NodeProperties::GetType(node)->Is(Type::Signed32())); } - bool CanLowerToInt32AdditiveBinop(Node* node, MachineTypeUnion use) { + bool CanLowerToWord32AdditiveBinop(Node* node, MachineTypeUnion use) { return BothInputsAre(node, safe_int_additive_range_) && - !CanObserveNonInt32(use); + !CanObserveNonWord32(use); } bool CanLowerToUint32Binop(Node* node, MachineTypeUnion use) { return BothInputsAre(node, Type::Unsigned32()) && - (!CanObserveNonUint32(use) || + (!CanObserveNonWord32(use) || NodeProperties::GetType(node)->Is(Type::Unsigned32())); } - bool CanLowerToUint32AdditiveBinop(Node* node, MachineTypeUnion use) { - return BothInputsAre(node, safe_int_additive_range_) && - !CanObserveNonUint32(use); - } - bool CanObserveNonWord32(MachineTypeUnion use) { - return (use & ~(kTypeUint32 | kTypeInt32)) != 0; - } - - bool CanObserveNonInt32(MachineTypeUnion use) { - return (use & (kTypeUint32 | kTypeNumber | kTypeAny)) != 0; - } - - bool CanObserveMinusZero(MachineTypeUnion use) { - // TODO(turbofan): technically Uint32 cannot observe minus zero either. - return (use & (kTypeUint32 | kTypeNumber | kTypeAny)) != 0; + return (use & kTypeMask & ~(kTypeInt32 | kTypeUint32)) != 0; } bool CanObserveNaN(MachineTypeUnion use) { return (use & (kTypeNumber | kTypeAny)) != 0; } - bool CanObserveNonUint32(MachineTypeUnion use) { - return (use & (kTypeInt32 | kTypeNumber | kTypeAny)) != 0; - } - // 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, MachineTypeUnion use, @@ -644,22 +625,16 @@ class RepresentationSelector { // => signed Int32Add/Sub VisitInt32Binop(node); if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); - } else if (CanLowerToInt32AdditiveBinop(node, use)) { - // => signed Int32Add/Sub, truncating inputs - ProcessTruncateWord32Input(node, 0, kTypeInt32); - ProcessTruncateWord32Input(node, 1, kTypeInt32); - SetOutput(node, kMachInt32); - if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); } else if (CanLowerToUint32Binop(node, use)) { // => unsigned Int32Add/Sub VisitUint32Binop(node); if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node)); - } else if (CanLowerToUint32AdditiveBinop(node, use)) { + } else if (CanLowerToWord32AdditiveBinop(node, use)) { // => signed Int32Add/Sub, truncating inputs - ProcessTruncateWord32Input(node, 0, kTypeUint32); - ProcessTruncateWord32Input(node, 1, kTypeUint32); - SetOutput(node, kMachUint32); - if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node)); + ProcessTruncateWord32Input(node, 0, kTypeInt32); + ProcessTruncateWord32Input(node, 1, kTypeInt32); + SetOutput(node, kMachInt32); + if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); } else { // => Float64Add/Sub VisitFloat64Binop(node); @@ -718,6 +693,13 @@ class RepresentationSelector { if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); break; } + case IrOpcode::kNumberBitwiseOr: + case IrOpcode::kNumberBitwiseXor: + case IrOpcode::kNumberBitwiseAnd: { + VisitInt32Binop(node); + if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); + break; + } case IrOpcode::kNumberShiftLeft: { VisitBinop(node, kMachInt32, kMachUint32, kMachInt32); if (lower()) lowering->DoShift(node, lowering->machine()->Word32Shl()); @@ -914,18 +896,16 @@ class RepresentationSelector { if (lower()) lowering->DoStoreElement(node); break; } + case IrOpcode::kObjectIsNumber: { + ProcessInput(node, 0, kMachAnyTagged); + SetOutput(node, kRepBit | kTypeBool); + if (lower()) lowering->DoObjectIsNumber(node); + break; + } case IrOpcode::kObjectIsSmi: { ProcessInput(node, 0, kMachAnyTagged); SetOutput(node, kRepBit | kTypeBool); - if (lower()) { - Node* is_tagged = jsgraph_->graph()->NewNode( - jsgraph_->machine()->WordAnd(), node->InputAt(0), - jsgraph_->IntPtrConstant(kSmiTagMask)); - Node* is_smi = jsgraph_->graph()->NewNode( - jsgraph_->machine()->WordEqual(), is_tagged, - jsgraph_->IntPtrConstant(kSmiTag)); - DeferReplacement(node, is_smi); - } + if (lower()) lowering->DoObjectIsSmi(node); break; } @@ -1146,14 +1126,6 @@ class RepresentationSelector { }; -Node* SimplifiedLowering::IsTagged(Node* node) { - // TODO(titzer): factor this out to a TaggingScheme abstraction. - STATIC_ASSERT(kSmiTagMask == 1); // Only works if tag is the low bit. - return graph()->NewNode(machine()->WordAnd(), node, - jsgraph()->Int32Constant(kSmiTagMask)); -} - - SimplifiedLowering::SimplifiedLowering(JSGraph* jsgraph, Zone* zone, SourcePositionTable* source_positions) : jsgraph_(jsgraph), @@ -1163,44 +1135,52 @@ SimplifiedLowering::SimplifiedLowering(JSGraph* jsgraph, Zone* zone, void SimplifiedLowering::LowerAllNodes() { - SimplifiedOperatorBuilder simplified(graph()->zone()); - RepresentationChanger changer(jsgraph(), &simplified, jsgraph()->isolate()); + RepresentationChanger changer(jsgraph(), jsgraph()->isolate()); RepresentationSelector selector(jsgraph(), zone_, &changer, source_positions_); selector.Run(this); } -Node* SimplifiedLowering::Untag(Node* node) { - // TODO(titzer): factor this out to a TaggingScheme abstraction. - Node* shift_amount = jsgraph()->Int32Constant(kSmiTagSize + kSmiShiftSize); - return graph()->NewNode(machine()->WordSar(), node, shift_amount); -} - - -Node* SimplifiedLowering::SmiTag(Node* node) { - // TODO(titzer): factor this out to a TaggingScheme abstraction. - Node* shift_amount = jsgraph()->Int32Constant(kSmiTagSize + kSmiShiftSize); - return graph()->NewNode(machine()->WordShl(), node, shift_amount); -} - - -Node* SimplifiedLowering::OffsetMinusTagConstant(int32_t offset) { - return jsgraph()->Int32Constant(offset - kHeapObjectTag); -} - - namespace { WriteBarrierKind ComputeWriteBarrierKind(BaseTaggedness base_is_tagged, MachineType representation, - Type* type) { - if (type->Is(Type::TaggedSigned())) { + Type* field_type, Type* input_type) { + if (field_type->Is(Type::TaggedSigned()) || + input_type->Is(Type::TaggedSigned())) { // Write barriers are only for writes of heap objects. return kNoWriteBarrier; } + if (input_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 (base_is_tagged == kTaggedBase && RepresentationOf(representation) == kRepTagged) { + if (input_type->IsConstant() && + input_type->AsConstant()->Value()->IsHeapObject()) { + Handle<HeapObject> input = + Handle<HeapObject>::cast(input_type->AsConstant()->Value()); + if (input->IsMap()) { + // Write barriers for storing maps are cheaper. + return kMapWriteBarrier; + } + Isolate* const isolate = input->GetIsolate(); + RootIndexMap root_index_map(isolate); + int root_index = root_index_map.Lookup(*input); + if (root_index != RootIndexMap::kInvalidRootIndex && + isolate->heap()->RootIsImmortalImmovable(root_index)) { + // Write barriers are unnecessary for immortal immovable roots. + return kNoWriteBarrier; + } + } + if (field_type->Is(Type::TaggedPointer()) || + input_type->Is(Type::TaggedPointer())) { + // Write barriers for heap objects don't need a Smi check. + return kPointerWriteBarrier; + } // Write barriers are only for writes into heap objects (i.e. tagged base). return kFullWriteBarrier; } @@ -1212,18 +1192,32 @@ WriteBarrierKind ComputeWriteBarrierKind(BaseTaggedness base_is_tagged, void SimplifiedLowering::DoAllocate(Node* node) { PretenureFlag pretenure = OpParameter<PretenureFlag>(node->op()); - AllocationSpace space = pretenure == TENURED ? OLD_SPACE : NEW_SPACE; - Runtime::FunctionId f = Runtime::kAllocateInTargetSpace; - Operator::Properties props = node->op()->properties(); - CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor(zone(), f, 2, props); - ExternalReference ref(f, jsgraph()->isolate()); - int32_t flags = AllocateTargetSpace::encode(space); - node->InsertInput(graph()->zone(), 0, jsgraph()->CEntryStubConstant(1)); - node->InsertInput(graph()->zone(), 2, jsgraph()->SmiConstant(flags)); - node->InsertInput(graph()->zone(), 3, jsgraph()->ExternalConstant(ref)); - node->InsertInput(graph()->zone(), 4, jsgraph()->Int32Constant(2)); - node->InsertInput(graph()->zone(), 5, jsgraph()->NoContextConstant()); - NodeProperties::ChangeOp(node, common()->Call(desc)); + if (pretenure == NOT_TENURED) { + Callable callable = CodeFactory::AllocateInNewSpace(isolate()); + Node* target = jsgraph()->HeapConstant(callable.code()); + CallDescriptor* descriptor = Linkage::GetStubCallDescriptor( + isolate(), jsgraph()->zone(), callable.descriptor(), 0, + CallDescriptor::kNoFlags, Operator::kNoThrow); + const Operator* op = common()->Call(descriptor); + node->InsertInput(graph()->zone(), 0, target); + node->InsertInput(graph()->zone(), 2, jsgraph()->NoContextConstant()); + NodeProperties::ChangeOp(node, op); + } else { + DCHECK_EQ(TENURED, pretenure); + AllocationSpace space = OLD_SPACE; + Runtime::FunctionId f = Runtime::kAllocateInTargetSpace; + Operator::Properties props = node->op()->properties(); + CallDescriptor* desc = + Linkage::GetRuntimeCallDescriptor(zone(), f, 2, props); + ExternalReference ref(f, jsgraph()->isolate()); + int32_t flags = AllocateTargetSpace::encode(space); + node->InsertInput(graph()->zone(), 0, jsgraph()->CEntryStubConstant(1)); + node->InsertInput(graph()->zone(), 2, jsgraph()->SmiConstant(flags)); + node->InsertInput(graph()->zone(), 3, jsgraph()->ExternalConstant(ref)); + node->InsertInput(graph()->zone(), 4, jsgraph()->Int32Constant(2)); + node->InsertInput(graph()->zone(), 5, jsgraph()->NoContextConstant()); + NodeProperties::ChangeOp(node, common()->Call(desc)); + } } @@ -1238,8 +1232,8 @@ void SimplifiedLowering::DoLoadField(Node* node) { void SimplifiedLowering::DoStoreField(Node* node) { const FieldAccess& access = FieldAccessOf(node->op()); Type* type = NodeProperties::GetType(node->InputAt(1)); - WriteBarrierKind kind = - ComputeWriteBarrierKind(access.base_is_tagged, access.machine_type, type); + WriteBarrierKind kind = ComputeWriteBarrierKind( + access.base_is_tagged, access.machine_type, access.type, type); Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag()); node->InsertInput(graph()->zone(), 1, offset); NodeProperties::ChangeOp( @@ -1347,10 +1341,47 @@ void SimplifiedLowering::DoStoreElement(Node* node) { Type* type = NodeProperties::GetType(node->InputAt(2)); node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1))); NodeProperties::ChangeOp( - node, machine()->Store(StoreRepresentation( - access.machine_type, - ComputeWriteBarrierKind(access.base_is_tagged, - access.machine_type, type)))); + node, + machine()->Store(StoreRepresentation( + access.machine_type, + ComputeWriteBarrierKind(access.base_is_tagged, access.machine_type, + access.type, type)))); +} + + +void SimplifiedLowering::DoObjectIsNumber(Node* node) { + Node* input = NodeProperties::GetValueInput(node, 0); + // TODO(bmeurer): Optimize somewhat based on input type. + Node* check = + graph()->NewNode(machine()->WordEqual(), + graph()->NewNode(machine()->WordAnd(), input, + jsgraph()->IntPtrConstant(kSmiTagMask)), + jsgraph()->IntPtrConstant(kSmiTag)); + Node* branch = graph()->NewNode(common()->Branch(), check, graph()->start()); + Node* if_true = graph()->NewNode(common()->IfTrue(), branch); + Node* vtrue = jsgraph()->Int32Constant(1); + Node* if_false = graph()->NewNode(common()->IfFalse(), branch); + Node* vfalse = graph()->NewNode( + machine()->WordEqual(), + graph()->NewNode( + machine()->Load(kMachAnyTagged), input, + jsgraph()->IntPtrConstant(HeapObject::kMapOffset - kHeapObjectTag), + graph()->start(), if_false), + jsgraph()->HeapConstant(isolate()->factory()->heap_number_map())); + Node* control = graph()->NewNode(common()->Merge(2), if_true, if_false); + node->ReplaceInput(0, vtrue); + node->AppendInput(graph()->zone(), vfalse); + node->AppendInput(graph()->zone(), control); + NodeProperties::ChangeOp(node, common()->Phi(kMachBool, 2)); +} + + +void SimplifiedLowering::DoObjectIsSmi(Node* node) { + node->ReplaceInput(0, + graph()->NewNode(machine()->WordAnd(), node->InputAt(0), + jsgraph()->IntPtrConstant(kSmiTagMask))); + node->AppendInput(graph()->zone(), jsgraph()->IntPtrConstant(kSmiTag)); + NodeProperties::ChangeOp(node, machine()->WordEqual()); } |