Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Unified Diff: src/compiler/simplified-lowering.cc

Issue 768543002: [WIP] TrapHandler 2014/11/27. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/simplified-lowering.h ('k') | src/compiler/simplified-operator.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/simplified-lowering.cc
diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc
index 8d770c0f9ffb97df479d7d0caa0f1871150cecac..5ce23b5064cb522bfe1ea91d161d9f2a0d707961 100644
--- a/src/compiler/simplified-lowering.cc
+++ b/src/compiler/simplified-lowering.cc
@@ -764,30 +764,51 @@ class RepresentationSelector {
ElementAccess access = ElementAccessOf(node->op());
ProcessInput(node, 0, changer_->TypeForBasePointer(access));
ProcessInput(node, 1, kMachInt32); // element index
- ProcessInput(node, 2, kMachInt32); // length
- ProcessRemainingInputs(node, 3);
- // Tagged overrides everything if we have to do a typed array bounds
- // check, because we may need to return undefined then.
- MachineType output_type =
- (access.bounds_check == kTypedArrayBoundsCheck &&
- (use & kRepTagged))
- ? kMachAnyTagged
- : access.machine_type;
- SetOutput(node, output_type);
- if (lower()) lowering->DoLoadElement(node, output_type);
+ ProcessRemainingInputs(node, 2);
+ SetOutput(node, access.machine_type);
+ if (lower()) lowering->DoLoadElement(node);
break;
}
case IrOpcode::kStoreElement: {
ElementAccess access = ElementAccessOf(node->op());
ProcessInput(node, 0, changer_->TypeForBasePointer(access));
ProcessInput(node, 1, kMachInt32); // element index
- ProcessInput(node, 2, kMachInt32); // length
- ProcessInput(node, 3, access.machine_type);
- ProcessRemainingInputs(node, 4);
+ ProcessInput(node, 2, access.machine_type);
+ ProcessRemainingInputs(node, 3);
SetOutput(node, 0);
if (lower()) lowering->DoStoreElement(node);
break;
}
+ case IrOpcode::kLoadBuffer: {
+ BufferAccess const access = BufferAccessOf(node->op());
+ ProcessInput(node, 0, kMachPtr); // buffer
+ ProcessInput(node, 1, kMachInt32); // offset
+ ProcessInput(node, 2, kMachUint32); // length
+ ProcessRemainingInputs(node, 3);
+ // Tagged overrides everything, because we may need to return undefined.
+ MachineType const output_type =
+ (use & kRepTagged) ? kMachAnyTagged : access.machine_type();
+ SetOutput(node, output_type);
+ if (lower()) lowering->DoLoadBuffer(node, output_type);
+ break;
+ }
+ case IrOpcode::kStoreBuffer: {
+ BufferAccess const access = BufferAccessOf(node->op());
+ ProcessInput(node, 0, kMachPtr); // buffer
+ ProcessInput(node, 1, kMachInt32); // offset
+ ProcessInput(node, 2, kMachUint32); // length
+ ProcessInput(node, 3, access.machine_type()); // value
+ ProcessRemainingInputs(node, 4);
+ SetOutput(node, 0);
+ if (lower()) lowering->DoStoreBuffer(node);
+ break;
+ }
+ case IrOpcode::kBoundsCheck: {
+ ProcessInput(node, 0, kRepWord32);
+ ProcessInput(node, 1, kMachUint32);
+ SetOutput(node, kMachUint32);
+ break;
+ }
case IrOpcode::kObjectIsSmi: {
ProcessInput(node, 0, kMachAnyTagged);
SetOutput(node, kRepBit | kTypeBool);
@@ -1031,8 +1052,7 @@ Node* SimplifiedLowering::IsTagged(Node* node) {
void SimplifiedLowering::LowerAllNodes() {
- SimplifiedOperatorBuilder simplified(graph()->zone());
- RepresentationChanger changer(jsgraph(), &simplified,
+ RepresentationChanger changer(jsgraph(), simplified(),
graph()->zone()->isolate());
RepresentationSelector selector(jsgraph(), zone(), &changer);
selector.Run(this);
@@ -1091,7 +1111,7 @@ void SimplifiedLowering::DoStoreField(Node* node) {
Node* SimplifiedLowering::ComputeIndex(const ElementAccess& access,
- Node* const key) {
+ Node* key) {
Node* index = key;
const int element_size_shift = ElementSizeLog2Of(access.machine_type);
if (element_size_shift) {
@@ -1104,155 +1124,156 @@ Node* SimplifiedLowering::ComputeIndex(const ElementAccess& access,
jsgraph()->Int32Constant(fixed_offset));
}
if (machine()->Is64()) {
- // TODO(turbofan): This is probably only correct for typed arrays, and only
- // if the typed arrays are at most 2GiB in size, which happens to match
- // exactly our current situation.
- index = graph()->NewNode(machine()->ChangeUint32ToUint64(), index);
+ index = graph()->NewNode(machine()->ChangeInt32ToInt64(), index);
}
return index;
}
-namespace {
-
-intptr_t AddressForOutOfBoundsLoad(MachineType type) {
- switch (RepresentationOf(type)) {
- case kRepFloat32: {
- static const float dummy = std::numeric_limits<float>::quiet_NaN();
- return bit_cast<intptr_t>(&dummy);
- }
- case kRepFloat64: {
- static const double dummy = std::numeric_limits<double>::quiet_NaN();
- return bit_cast<intptr_t>(&dummy);
- }
- case kRepBit:
- case kRepWord8:
- case kRepWord16:
- case kRepWord32: {
- static const int32_t dummy = 0;
- return bit_cast<intptr_t>(&dummy);
- }
- default:
- break;
+Node* SimplifiedLowering::ComputeOffset(const BufferAccess& access,
+ Node* offset) {
+ int const element_size = ElementSizeOf(access.machine_type());
+ DCHECK_LE(1, element_size);
+ if (element_size > 1) {
+ offset = graph()->NewNode(machine()->Word32And(), offset,
+ jsgraph()->Int32Constant(~(element_size - 1)));
}
- UNREACHABLE();
- return 0;
+ if (machine()->Is64()) {
+ // TODO(turbofan): This is probably only correct for typed arrays, and only
+ // if the typed arrays are at most 2GiB in size, which happens to match
+ // exactly our current situation.
+ offset = graph()->NewNode(machine()->ChangeUint32ToUint64(), offset);
+ }
+ return offset;
}
-intptr_t AddressForOutOfBoundsStore() {
- static volatile double dummy = 0;
- return bit_cast<intptr_t>(&dummy);
+void SimplifiedLowering::DoLoadElement(Node* node) {
+ const ElementAccess& access = ElementAccessOf(node->op());
+ Node* key = node->InputAt(1);
+ Node* index = ComputeIndex(access, key);
+ node->set_op(machine()->Load(access.machine_type));
+ node->ReplaceInput(1, index);
}
-} // namespace
-
-void SimplifiedLowering::DoLoadElement(Node* node, MachineType output_type) {
+void SimplifiedLowering::DoStoreElement(Node* node) {
const ElementAccess& access = ElementAccessOf(node->op());
- const Operator* op = machine()->Load(access.machine_type);
Node* key = node->InputAt(1);
Node* index = ComputeIndex(access, key);
+ node->set_op(machine()->Store(StoreRepresentation(
+ access.machine_type,
+ ComputeWriteBarrierKind(access.base_is_tagged, access.machine_type,
+ access.type))));
+ node->ReplaceInput(1, index);
+}
+
+
+void SimplifiedLowering::DoLoadBuffer(Node* node, MachineType output_type) {
+ BufferAccess const access = BufferAccessOf(node->op());
+ Node* buffer = node->InputAt(0);
+ Node* offset = node->InputAt(1);
+ Node* length = node->InputAt(2);
Node* effect = node->InputAt(3);
- if (access.bounds_check == kNoBoundsCheck) {
- DCHECK_EQ(access.machine_type, output_type);
- node->set_op(op);
- node->ReplaceInput(1, index);
- node->ReplaceInput(2, effect);
- node->ReplaceInput(3, graph()->start());
- } else {
- DCHECK_EQ(kTypedArrayBoundsCheck, access.bounds_check);
-
- Node* base = node->InputAt(0);
- Node* length = node->InputAt(2);
- Node* check = graph()->NewNode(machine()->Uint32LessThan(), key, length);
-
- IntPtrMatcher mbase(base);
- if (mbase.HasValue() && (output_type & kRepTagged) == 0) {
- Node* select = graph()->NewNode(
- common()->Select(kMachIntPtr, BranchHint::kTrue), check, index,
- jsgraph()->IntPtrConstant(AddressForOutOfBoundsLoad(output_type) -
- mbase.Value()));
-
- node->set_op(op);
- node->ReplaceInput(1, select);
- node->ReplaceInput(2, effect);
- node->ReplaceInput(3, graph()->start());
+ Node* control = node->InputAt(4);
+ size_t const element_size = ElementSizeOf(access.machine_type());
+ if (output_type & kRepTagged || access.guard_size() < element_size) {
+ Node* check = graph()->NewNode(machine()->Uint32LessThan(), offset, length);
+ Node* branch =
+ graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
+
+ Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+ Node* vtrue =
+ graph()->NewNode(machine()->Load(access.machine_type()), buffer,
+ ComputeOffset(access, offset), effect, if_true);
+ Node* etrue = vtrue;
+ if (output_type & kRepTagged) {
+ // TODO(turbofan): This is ugly as hell!
+ RepresentationChanger changer(jsgraph(), simplified(),
+ graph()->zone()->isolate());
+ vtrue = changer.GetTaggedRepresentationFor(vtrue, access.machine_type());
+ }
+
+ Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+ Node* vfalse;
+ // TODO(bmeurer): Refactor this into a separate method.
+ if (output_type & kRepTagged) {
+ DCHECK_EQ(0, access.machine_type() & kRepTagged);
+ vfalse = jsgraph()->UndefinedConstant();
+ } else if (output_type & kRepFloat32) {
+ vfalse =
+ jsgraph()->Float32Constant(std::numeric_limits<float>::quiet_NaN());
+ } else if (output_type & kRepFloat64) {
+ vfalse =
+ jsgraph()->Float64Constant(std::numeric_limits<double>::quiet_NaN());
} else {
- Diamond d(graph(), common(), check, BranchHint::kTrue);
-
- Node* load = graph()->NewNode(op, base, index, effect, d.if_true);
- Node* result = load;
- if (output_type & kRepTagged) {
- // TODO(turbofan): This is ugly as hell!
- SimplifiedOperatorBuilder simplified(graph()->zone());
- RepresentationChanger changer(jsgraph(), &simplified,
- graph()->zone()->isolate());
- result =
- changer.GetTaggedRepresentationFor(result, access.machine_type);
- }
+ vfalse = jsgraph()->Int32Constant(0);
+ }
+ Node* efalse = effect;
- Node* undefined;
- if (output_type & kRepTagged) {
- DCHECK_EQ(0, access.machine_type & kRepTagged);
- undefined = jsgraph()->UndefinedConstant();
- } else if (output_type & kRepFloat32) {
- undefined =
- jsgraph()->Float32Constant(std::numeric_limits<float>::quiet_NaN());
- } else if (output_type & kRepFloat64) {
- undefined = jsgraph()->Float64Constant(
- std::numeric_limits<double>::quiet_NaN());
- } else {
- undefined = jsgraph()->Int32Constant(0);
- }
+ Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
+ Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge);
- // Replace effect uses of node with the effect phi.
- NodeProperties::ReplaceWithValue(node, node, d.EffectPhi(load, effect));
+ // Replace effect uses of {node} with the EffectPhi {ephi}.
+ NodeProperties::ReplaceWithValue(node, node, ephi);
- d.OverwriteWithPhi(node, output_type, result, undefined);
- }
+ // Turn the {node} into a Phi.
+ node->set_op(common()->Phi(output_type, 2));
+ node->ReplaceInput(0, vtrue);
+ node->ReplaceInput(1, vfalse);
+ node->ReplaceInput(2, merge);
+ node->TrimInputCount(3);
+ } else {
+ offset = graph()->NewNode(
+ simplified()->BoundsCheck(access.guard_size() - element_size), offset,
+ length);
+ node->set_op(machine()->Load(access.machine_type()));
+ DCHECK_EQ(buffer, node->InputAt(0));
+ node->ReplaceInput(1, ComputeOffset(access, offset));
+ node->RemoveInput(2);
}
}
-void SimplifiedLowering::DoStoreElement(Node* node) {
- const ElementAccess& access = ElementAccessOf(node->op());
- const Operator* op = machine()->Store(StoreRepresentation(
- access.machine_type,
- ComputeWriteBarrierKind(access.base_is_tagged, access.machine_type,
- access.type)));
- Node* key = node->InputAt(1);
- Node* index = ComputeIndex(access, key);
- if (access.bounds_check == kNoBoundsCheck) {
- node->set_op(op);
- node->ReplaceInput(1, index);
- node->RemoveInput(2);
+void SimplifiedLowering::DoStoreBuffer(Node* node) {
+ BufferAccess const access = BufferAccessOf(node->op());
+ Node* buffer = node->InputAt(0);
+ Node* offset = node->InputAt(1);
+ Node* length = node->InputAt(2);
+ Node* value = node->InputAt(3);
+ Node* effect = node->InputAt(4);
+ Node* control = node->InputAt(5);
+ size_t const element_size = ElementSizeOf(access.machine_type());
+ if (access.guard_size() < element_size) {
+ Node* check = graph()->NewNode(machine()->Uint32LessThan(), offset, length);
+ Node* branch =
+ graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
+
+ Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+ Node* etrue = graph()->NewNode(machine()->Store(StoreRepresentation(
+ access.machine_type(), kNoWriteBarrier)),
+ buffer, ComputeOffset(access, offset), value,
+ effect, if_true);
+
+ Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+ Node* efalse = effect;
+
+ Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
+
+ // Turn the {node} into an EffectPhi.
+ node->set_op(common()->EffectPhi(2));
+ node->ReplaceInput(0, etrue);
+ node->ReplaceInput(1, efalse);
+ node->ReplaceInput(2, merge);
+ node->TrimInputCount(3);
} else {
- DCHECK_EQ(kTypedArrayBoundsCheck, access.bounds_check);
-
- Node* base = node->InputAt(0);
- Node* length = node->InputAt(2);
- Node* value = node->InputAt(3);
- Node* effect = node->InputAt(4);
- Node* control = node->InputAt(5);
- Node* check = graph()->NewNode(machine()->Uint32LessThan(), key, length);
-
- IntPtrMatcher mbase(base);
- if (mbase.HasValue()) {
- Node* select = graph()->NewNode(
- common()->Select(kMachIntPtr, BranchHint::kTrue), check, index,
- jsgraph()->IntPtrConstant(AddressForOutOfBoundsStore() -
- mbase.Value()));
-
- node->set_op(op);
- node->ReplaceInput(1, select);
- node->RemoveInput(2);
- } else {
- Diamond d(graph(), common(), check, BranchHint::kTrue);
- d.Chain(control);
- Node* store = graph()->NewNode(op, base, index, value, effect, d.if_true);
- d.OverwriteWithEffectPhi(node, store, effect);
- }
+ offset = graph()->NewNode(
+ simplified()->BoundsCheck(access.guard_size() - element_size), offset,
+ length);
+ node->set_op(machine()->Store(
+ StoreRepresentation(access.machine_type(), kNoWriteBarrier)));
+ node->ReplaceInput(1, ComputeOffset(access, offset));
+ node->RemoveInput(2);
}
}
« no previous file with comments | « src/compiler/simplified-lowering.h ('k') | src/compiler/simplified-operator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698