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

Side by Side Diff: src/compiler/simplified-lowering.cc

Issue 640603003: [turbofan] Properly emit bounds checks for typed array element loads. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Add another test. Created 6 years, 2 months 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/compiler/simplified-lowering.h ('k') | test/cctest/compiler/test-representation-change.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/simplified-lowering.h" 5 #include "src/compiler/simplified-lowering.h"
6 6
7 #include <limits>
8
7 #include "src/base/bits.h" 9 #include "src/base/bits.h"
8 #include "src/code-factory.h" 10 #include "src/code-factory.h"
9 #include "src/compiler/common-operator.h" 11 #include "src/compiler/common-operator.h"
10 #include "src/compiler/graph-inl.h" 12 #include "src/compiler/graph-inl.h"
11 #include "src/compiler/node-matchers.h" 13 #include "src/compiler/node-matchers.h"
12 #include "src/compiler/node-properties-inl.h" 14 #include "src/compiler/node-properties-inl.h"
13 #include "src/compiler/representation-change.h" 15 #include "src/compiler/representation-change.h"
14 #include "src/compiler/simplified-lowering.h" 16 #include "src/compiler/simplified-lowering.h"
15 #include "src/compiler/simplified-operator.h" 17 #include "src/compiler/simplified-operator.h"
16 #include "src/objects.h" 18 #include "src/objects.h"
(...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 SetOutput(node, 0); 660 SetOutput(node, 0);
659 if (lower()) lowering->DoStoreField(node); 661 if (lower()) lowering->DoStoreField(node);
660 break; 662 break;
661 } 663 }
662 case IrOpcode::kLoadElement: { 664 case IrOpcode::kLoadElement: {
663 ElementAccess access = ElementAccessOf(node->op()); 665 ElementAccess access = ElementAccessOf(node->op());
664 ProcessInput(node, 0, changer_->TypeForBasePointer(access)); 666 ProcessInput(node, 0, changer_->TypeForBasePointer(access));
665 ProcessInput(node, 1, kMachInt32); // element index 667 ProcessInput(node, 1, kMachInt32); // element index
666 ProcessInput(node, 2, kMachInt32); // length 668 ProcessInput(node, 2, kMachInt32); // length
667 ProcessRemainingInputs(node, 3); 669 ProcessRemainingInputs(node, 3);
668 SetOutput(node, access.machine_type); 670 // Tagged overrides everything if we have to do a typed array bounds
669 if (lower()) lowering->DoLoadElement(node); 671 // check, because we may need to return undefined then.
672 MachineType output_type =
673 (access.bounds_check == kTypedArrayBoundsCheck &&
674 (use & kRepTagged))
675 ? kMachAnyTagged
676 : access.machine_type;
677 SetOutput(node, output_type);
678 if (lower()) lowering->DoLoadElement(node, output_type);
670 break; 679 break;
671 } 680 }
672 case IrOpcode::kStoreElement: { 681 case IrOpcode::kStoreElement: {
673 ElementAccess access = ElementAccessOf(node->op()); 682 ElementAccess access = ElementAccessOf(node->op());
674 ProcessInput(node, 0, changer_->TypeForBasePointer(access)); 683 ProcessInput(node, 0, changer_->TypeForBasePointer(access));
675 ProcessInput(node, 1, kMachInt32); // element index 684 ProcessInput(node, 1, kMachInt32); // element index
676 ProcessInput(node, 2, kMachInt32); // length 685 ProcessInput(node, 2, kMachInt32); // length
677 ProcessInput(node, 3, access.machine_type); 686 ProcessInput(node, 3, access.machine_type);
678 ProcessRemainingInputs(node, 4); 687 ProcessRemainingInputs(node, 4);
679 SetOutput(node, 0); 688 SetOutput(node, 0);
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
950 index = graph()->NewNode(machine()->Int32Mul(), 959 index = graph()->NewNode(machine()->Int32Mul(),
951 jsgraph()->Int32Constant(element_size), index); 960 jsgraph()->Int32Constant(element_size), index);
952 } 961 }
953 int fixed_offset = access.header_size - access.tag(); 962 int fixed_offset = access.header_size - access.tag();
954 if (fixed_offset == 0) return index; 963 if (fixed_offset == 0) return index;
955 return graph()->NewNode(machine()->Int32Add(), index, 964 return graph()->NewNode(machine()->Int32Add(), index,
956 jsgraph()->Int32Constant(fixed_offset)); 965 jsgraph()->Int32Constant(fixed_offset));
957 } 966 }
958 967
959 968
960 void SimplifiedLowering::DoLoadElement(Node* node) { 969 void SimplifiedLowering::DoLoadElement(Node* node, MachineType output_type) {
961 const ElementAccess& access = ElementAccessOf(node->op()); 970 const ElementAccess& access = ElementAccessOf(node->op());
962 node->set_op(machine()->Load(access.machine_type)); 971 const Operator* op = machine()->Load(access.machine_type);
963 node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1))); 972 Node* key = node->InputAt(1);
964 node->RemoveInput(2); 973 Node* index = ComputeIndex(access, key);
974 if (access.bounds_check == kNoBoundsCheck) {
975 DCHECK_EQ(access.machine_type, output_type);
976 node->set_op(op);
977 node->ReplaceInput(1, index);
978 node->RemoveInput(2);
979 } else {
980 DCHECK_EQ(kTypedArrayBoundsCheck, access.bounds_check);
981
982 Node* base = node->InputAt(0);
983 Node* length = node->InputAt(2);
984 Node* effect = node->InputAt(3);
985 Node* control = node->InputAt(4);
986
987 Node* check = graph()->NewNode(machine()->Uint32LessThan(), key, length);
988 Node* branch = graph()->NewNode(common()->Branch(), check, control);
989
990 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
991 Node* load = graph()->NewNode(op, base, index, effect, if_true);
992 Node* result = load;
993 if (output_type & kRepTagged) {
994 // TODO(turbofan): This is ugly as hell!
995 SimplifiedOperatorBuilder simplified(graph()->zone());
996 RepresentationChanger changer(jsgraph(), &simplified,
997 graph()->zone()->isolate());
998 result = changer.GetTaggedRepresentationFor(result, access.machine_type);
999 }
1000
1001 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1002 Node* undefined;
1003 if (output_type & kRepTagged) {
1004 DCHECK(!(access.machine_type & kRepTagged));
1005 undefined = jsgraph()->UndefinedConstant();
1006 } else if (output_type & kRepFloat32) {
1007 undefined =
1008 jsgraph()->Float32Constant(std::numeric_limits<float>::quiet_NaN());
1009 } else if (output_type & kRepFloat64) {
1010 undefined =
1011 jsgraph()->Float64Constant(std::numeric_limits<double>::quiet_NaN());
1012 } else {
1013 undefined = jsgraph()->Int32Constant(0);
1014 }
1015
1016 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
1017 Node* phi = graph()->NewNode(common()->EffectPhi(2), load, effect, merge);
1018
1019 // Replace effect uses of node with the effect phi.
1020 for (UseIter i = node->uses().begin(); i != node->uses().end();) {
1021 if (NodeProperties::IsEffectEdge(i.edge())) {
1022 i = i.UpdateToAndIncrement(phi);
1023 } else {
1024 ++i;
1025 }
1026 }
1027
1028 node->set_op(common()->Phi(output_type, 2));
1029 node->ReplaceInput(0, result);
1030 node->ReplaceInput(1, undefined);
1031 node->ReplaceInput(2, merge);
1032 node->TrimInputCount(3);
1033 }
965 } 1034 }
966 1035
967 1036
968 void SimplifiedLowering::DoStoreElement(Node* node) { 1037 void SimplifiedLowering::DoStoreElement(Node* node) {
969 const ElementAccess& access = ElementAccessOf(node->op()); 1038 const ElementAccess& access = ElementAccessOf(node->op());
970 const Operator* op = machine()->Store(StoreRepresentation( 1039 const Operator* op = machine()->Store(StoreRepresentation(
971 access.machine_type, 1040 access.machine_type,
972 ComputeWriteBarrierKind(access.base_is_tagged, access.machine_type, 1041 ComputeWriteBarrierKind(access.base_is_tagged, access.machine_type,
973 access.type))); 1042 access.type)));
974 Node* key = node->InputAt(1); 1043 Node* key = node->InputAt(1);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1055 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { 1124 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) {
1056 node->set_op(machine()->IntLessThanOrEqual()); 1125 node->set_op(machine()->IntLessThanOrEqual());
1057 node->ReplaceInput(0, StringComparison(node, true)); 1126 node->ReplaceInput(0, StringComparison(node, true));
1058 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); 1127 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL));
1059 } 1128 }
1060 1129
1061 1130
1062 } // namespace compiler 1131 } // namespace compiler
1063 } // namespace internal 1132 } // namespace internal
1064 } // namespace v8 1133 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/simplified-lowering.h ('k') | test/cctest/compiler/test-representation-change.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698