OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/effect-control-linearizer.h" | 5 #include "src/compiler/effect-control-linearizer.h" |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/compiler/access-builder.h" | 8 #include "src/compiler/access-builder.h" |
9 #include "src/compiler/js-graph.h" | 9 #include "src/compiler/js-graph.h" |
10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
401 break; | 401 break; |
402 case IrOpcode::kObjectIsSmi: | 402 case IrOpcode::kObjectIsSmi: |
403 state = LowerObjectIsSmi(node, *effect, *control); | 403 state = LowerObjectIsSmi(node, *effect, *control); |
404 break; | 404 break; |
405 case IrOpcode::kObjectIsString: | 405 case IrOpcode::kObjectIsString: |
406 state = LowerObjectIsString(node, *effect, *control); | 406 state = LowerObjectIsString(node, *effect, *control); |
407 break; | 407 break; |
408 case IrOpcode::kObjectIsUndetectable: | 408 case IrOpcode::kObjectIsUndetectable: |
409 state = LowerObjectIsUndetectable(node, *effect, *control); | 409 state = LowerObjectIsUndetectable(node, *effect, *control); |
410 break; | 410 break; |
| 411 case IrOpcode::kStringFromCharCode: |
| 412 state = LowerStringFromCharCode(node, *effect, *control); |
| 413 break; |
411 default: | 414 default: |
412 return false; | 415 return false; |
413 } | 416 } |
414 NodeProperties::ReplaceUses(node, state.value); | 417 NodeProperties::ReplaceUses(node, state.value); |
415 *effect = state.effect; | 418 *effect = state.effect; |
416 *control = state.control; | 419 *control = state.control; |
417 return true; | 420 return true; |
418 } | 421 } |
419 | 422 |
420 EffectControlLinearizer::ValueEffectControl | 423 EffectControlLinearizer::ValueEffectControl |
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
920 | 923 |
921 control = graph()->NewNode(common()->Merge(2), if_true, if_false); | 924 control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
922 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); | 925 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
923 value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue, | 926 value = graph()->NewNode(common()->Phi(MachineRepresentation::kBit, 2), vtrue, |
924 vfalse, control); | 927 vfalse, control); |
925 | 928 |
926 return ValueEffectControl(value, effect, control); | 929 return ValueEffectControl(value, effect, control); |
927 } | 930 } |
928 | 931 |
929 EffectControlLinearizer::ValueEffectControl | 932 EffectControlLinearizer::ValueEffectControl |
| 933 EffectControlLinearizer::LowerStringFromCharCode(Node* node, Node* effect, |
| 934 Node* control) { |
| 935 Node* value = node->InputAt(0); |
| 936 |
| 937 // Compute the character code. |
| 938 Node* code = |
| 939 graph()->NewNode(machine()->Word32And(), value, |
| 940 jsgraph()->Int32Constant(String::kMaxUtf16CodeUnit)); |
| 941 |
| 942 // Check if the {code} is a one-byte char code. |
| 943 Node* check0 = |
| 944 graph()->NewNode(machine()->Int32LessThanOrEqual(), code, |
| 945 jsgraph()->Int32Constant(String::kMaxOneByteCharCode)); |
| 946 Node* branch0 = |
| 947 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control); |
| 948 |
| 949 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0); |
| 950 Node* etrue0 = effect; |
| 951 Node* vtrue0; |
| 952 { |
| 953 // Load the isolate wide single character string cache. |
| 954 Node* cache = |
| 955 jsgraph()->HeapConstant(factory()->single_character_string_cache()); |
| 956 |
| 957 // Compute the {cache} index for {code}. |
| 958 Node* index = |
| 959 machine()->Is32() ? code : graph()->NewNode( |
| 960 machine()->ChangeUint32ToUint64(), code); |
| 961 |
| 962 // Check if we have an entry for the {code} in the single character string |
| 963 // cache already. |
| 964 Node* entry = etrue0 = graph()->NewNode( |
| 965 simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()), cache, |
| 966 index, etrue0, if_true0); |
| 967 |
| 968 Node* check1 = graph()->NewNode(machine()->WordEqual(), entry, |
| 969 jsgraph()->UndefinedConstant()); |
| 970 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
| 971 check1, if_true0); |
| 972 |
| 973 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); |
| 974 Node* etrue1 = etrue0; |
| 975 Node* vtrue1; |
| 976 { |
| 977 // Allocate a new SeqOneByteString for {code}. |
| 978 vtrue1 = etrue1 = graph()->NewNode( |
| 979 simplified()->Allocate(NOT_TENURED), |
| 980 jsgraph()->Int32Constant(SeqOneByteString::SizeFor(1)), etrue1, |
| 981 if_true1); |
| 982 etrue1 = graph()->NewNode( |
| 983 simplified()->StoreField(AccessBuilder::ForMap()), vtrue1, |
| 984 jsgraph()->HeapConstant(factory()->one_byte_string_map()), etrue1, |
| 985 if_true1); |
| 986 etrue1 = graph()->NewNode( |
| 987 simplified()->StoreField(AccessBuilder::ForNameHashField()), vtrue1, |
| 988 jsgraph()->IntPtrConstant(Name::kEmptyHashField), etrue1, if_true1); |
| 989 etrue1 = graph()->NewNode( |
| 990 simplified()->StoreField(AccessBuilder::ForStringLength()), vtrue1, |
| 991 jsgraph()->SmiConstant(1), etrue1, if_true1); |
| 992 etrue1 = graph()->NewNode( |
| 993 machine()->Store(StoreRepresentation(MachineRepresentation::kWord8, |
| 994 kNoWriteBarrier)), |
| 995 vtrue1, jsgraph()->IntPtrConstant(SeqOneByteString::kHeaderSize - |
| 996 kHeapObjectTag), |
| 997 code, etrue1, if_true1); |
| 998 |
| 999 // Remember it in the {cache}. |
| 1000 etrue1 = graph()->NewNode( |
| 1001 simplified()->StoreElement(AccessBuilder::ForFixedArrayElement()), |
| 1002 cache, index, vtrue1, etrue1, if_true1); |
| 1003 } |
| 1004 |
| 1005 // Use the {entry} from the {cache}. |
| 1006 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); |
| 1007 Node* efalse1 = etrue0; |
| 1008 Node* vfalse1 = entry; |
| 1009 |
| 1010 if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1); |
| 1011 etrue0 = |
| 1012 graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_true0); |
| 1013 vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), |
| 1014 vtrue1, vfalse1, if_true0); |
| 1015 } |
| 1016 |
| 1017 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0); |
| 1018 Node* efalse0 = effect; |
| 1019 Node* vfalse0; |
| 1020 { |
| 1021 // Allocate a new SeqTwoByteString for {code}. |
| 1022 vfalse0 = efalse0 = |
| 1023 graph()->NewNode(simplified()->Allocate(NOT_TENURED), |
| 1024 jsgraph()->Int32Constant(SeqTwoByteString::SizeFor(1)), |
| 1025 efalse0, if_false0); |
| 1026 efalse0 = graph()->NewNode( |
| 1027 simplified()->StoreField(AccessBuilder::ForMap()), vfalse0, |
| 1028 jsgraph()->HeapConstant(factory()->string_map()), efalse0, if_false0); |
| 1029 efalse0 = graph()->NewNode( |
| 1030 simplified()->StoreField(AccessBuilder::ForNameHashField()), vfalse0, |
| 1031 jsgraph()->IntPtrConstant(Name::kEmptyHashField), efalse0, if_false0); |
| 1032 efalse0 = graph()->NewNode( |
| 1033 simplified()->StoreField(AccessBuilder::ForStringLength()), vfalse0, |
| 1034 jsgraph()->SmiConstant(1), efalse0, if_false0); |
| 1035 efalse0 = graph()->NewNode( |
| 1036 machine()->Store(StoreRepresentation(MachineRepresentation::kWord16, |
| 1037 kNoWriteBarrier)), |
| 1038 vfalse0, jsgraph()->IntPtrConstant(SeqTwoByteString::kHeaderSize - |
| 1039 kHeapObjectTag), |
| 1040 code, efalse0, if_false0); |
| 1041 } |
| 1042 |
| 1043 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0); |
| 1044 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control); |
| 1045 value = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), |
| 1046 vtrue0, vfalse0, control); |
| 1047 |
| 1048 return ValueEffectControl(value, effect, control); |
| 1049 } |
| 1050 |
| 1051 EffectControlLinearizer::ValueEffectControl |
930 EffectControlLinearizer::AllocateHeapNumberWithValue(Node* value, Node* effect, | 1052 EffectControlLinearizer::AllocateHeapNumberWithValue(Node* value, Node* effect, |
931 Node* control) { | 1053 Node* control) { |
932 Node* result = effect = graph()->NewNode( | 1054 Node* result = effect = graph()->NewNode( |
933 simplified()->Allocate(NOT_TENURED), | 1055 simplified()->Allocate(NOT_TENURED), |
934 jsgraph()->Int32Constant(HeapNumber::kSize), effect, control); | 1056 jsgraph()->Int32Constant(HeapNumber::kSize), effect, control); |
935 effect = graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()), | 1057 effect = graph()->NewNode(simplified()->StoreField(AccessBuilder::ForMap()), |
936 result, jsgraph()->HeapNumberMapConstant(), effect, | 1058 result, jsgraph()->HeapNumberMapConstant(), effect, |
937 control); | 1059 control); |
938 effect = graph()->NewNode( | 1060 effect = graph()->NewNode( |
939 simplified()->StoreField(AccessBuilder::ForHeapNumberValue()), result, | 1061 simplified()->StoreField(AccessBuilder::ForHeapNumberValue()), result, |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
980 } | 1102 } |
981 | 1103 |
982 Node* EffectControlLinearizer::SmiMaxValueConstant() { | 1104 Node* EffectControlLinearizer::SmiMaxValueConstant() { |
983 return jsgraph()->Int32Constant(Smi::kMaxValue); | 1105 return jsgraph()->Int32Constant(Smi::kMaxValue); |
984 } | 1106 } |
985 | 1107 |
986 Node* EffectControlLinearizer::SmiShiftBitsConstant() { | 1108 Node* EffectControlLinearizer::SmiShiftBitsConstant() { |
987 return jsgraph()->IntPtrConstant(kSmiShiftSize + kSmiTagSize); | 1109 return jsgraph()->IntPtrConstant(kSmiShiftSize + kSmiTagSize); |
988 } | 1110 } |
989 | 1111 |
| 1112 Factory* EffectControlLinearizer::factory() const { |
| 1113 return isolate()->factory(); |
| 1114 } |
| 1115 |
| 1116 Isolate* EffectControlLinearizer::isolate() const { |
| 1117 return jsgraph()->isolate(); |
| 1118 } |
| 1119 |
990 } // namespace compiler | 1120 } // namespace compiler |
991 } // namespace internal | 1121 } // namespace internal |
992 } // namespace v8 | 1122 } // namespace v8 |
OLD | NEW |