OLD | NEW |
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/code-factory.h" | 5 #include "src/code-factory.h" |
6 #include "src/compilation-dependencies.h" | 6 #include "src/compilation-dependencies.h" |
7 #include "src/compiler/access-builder.h" | 7 #include "src/compiler/access-builder.h" |
8 #include "src/compiler/js-graph.h" | 8 #include "src/compiler/js-graph.h" |
9 #include "src/compiler/js-typed-lowering.h" | 9 #include "src/compiler/js-typed-lowering.h" |
10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
(...skipping 1871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1882 } | 1882 } |
1883 if (vtrue_type->Is(false_type_) && vfalse_type->Is(true_type_)) { | 1883 if (vtrue_type->Is(false_type_) && vfalse_type->Is(true_type_)) { |
1884 // Select(condition, vtrue:false, vfalse:true) => BooleanNot(condition) | 1884 // Select(condition, vtrue:false, vfalse:true) => BooleanNot(condition) |
1885 node->TrimInputCount(1); | 1885 node->TrimInputCount(1); |
1886 NodeProperties::ChangeOp(node, simplified()->BooleanNot()); | 1886 NodeProperties::ChangeOp(node, simplified()->BooleanNot()); |
1887 return Changed(node); | 1887 return Changed(node); |
1888 } | 1888 } |
1889 return NoChange(); | 1889 return NoChange(); |
1890 } | 1890 } |
1891 | 1891 |
| 1892 namespace { |
| 1893 |
| 1894 MaybeHandle<Map> GetStableMapFromObjectType(Type* object_type) { |
| 1895 if (object_type->IsConstant() && |
| 1896 object_type->AsConstant()->Value()->IsHeapObject()) { |
| 1897 Handle<Map> object_map( |
| 1898 Handle<HeapObject>::cast(object_type->AsConstant()->Value())->map()); |
| 1899 if (object_map->is_stable()) return object_map; |
| 1900 } else if (object_type->IsClass()) { |
| 1901 Handle<Map> object_map = object_type->AsClass()->Map(); |
| 1902 if (object_map->is_stable()) return object_map; |
| 1903 } |
| 1904 return MaybeHandle<Map>(); |
| 1905 } |
| 1906 |
| 1907 } // namespace |
| 1908 |
| 1909 Reduction JSTypedLowering::ReduceCheckMaps(Node* node) { |
| 1910 // TODO(bmeurer): Find a better home for this thing! |
| 1911 // The CheckMaps(o, ...map...) can be eliminated if map is stable and |
| 1912 // either |
| 1913 // (a) o has type Constant(object) and map == object->map, or |
| 1914 // (b) o has type Class(map), |
| 1915 // and either |
| 1916 // (1) map cannot transition further, or |
| 1917 // (2) we can add a code dependency on the stability of map |
| 1918 // (to guard the Constant type information). |
| 1919 Node* const object = NodeProperties::GetValueInput(node, 0); |
| 1920 Type* const object_type = NodeProperties::GetType(object); |
| 1921 Node* const effect = NodeProperties::GetEffectInput(node); |
| 1922 Handle<Map> object_map; |
| 1923 if (GetStableMapFromObjectType(object_type).ToHandle(&object_map)) { |
| 1924 for (int i = 1; i < node->op()->ValueInputCount(); ++i) { |
| 1925 Node* const map = NodeProperties::GetValueInput(node, i); |
| 1926 Type* const map_type = NodeProperties::GetType(map); |
| 1927 if (map_type->IsConstant() && |
| 1928 map_type->AsConstant()->Value().is_identical_to(object_map)) { |
| 1929 if (object_map->CanTransition()) { |
| 1930 DCHECK(flags() & kDeoptimizationEnabled); |
| 1931 dependencies()->AssumeMapStable(object_map); |
| 1932 } |
| 1933 return Replace(effect); |
| 1934 } |
| 1935 } |
| 1936 } |
| 1937 return NoChange(); |
| 1938 } |
| 1939 |
1892 Reduction JSTypedLowering::ReduceCheckString(Node* node) { | 1940 Reduction JSTypedLowering::ReduceCheckString(Node* node) { |
1893 // TODO(bmeurer): Find a better home for this thing! | 1941 // TODO(bmeurer): Find a better home for this thing! |
1894 Node* const input = NodeProperties::GetValueInput(node, 0); | 1942 Node* const input = NodeProperties::GetValueInput(node, 0); |
1895 Type* const input_type = NodeProperties::GetType(input); | 1943 Type* const input_type = NodeProperties::GetType(input); |
1896 if (input_type->Is(Type::String())) { | 1944 if (input_type->Is(Type::String())) { |
1897 ReplaceWithValue(node, input); | 1945 ReplaceWithValue(node, input); |
1898 return Replace(input); | 1946 return Replace(input); |
1899 } | 1947 } |
1900 return NoChange(); | 1948 return NoChange(); |
1901 } | 1949 } |
1902 | 1950 |
| 1951 Reduction JSTypedLowering::ReduceLoadField(Node* node) { |
| 1952 // TODO(bmeurer): Find a better home for this thing! |
| 1953 Node* const object = NodeProperties::GetValueInput(node, 0); |
| 1954 Type* const object_type = NodeProperties::GetType(object); |
| 1955 FieldAccess const& access = FieldAccessOf(node->op()); |
| 1956 if (access.base_is_tagged == kTaggedBase && |
| 1957 access.offset == HeapObject::kMapOffset) { |
| 1958 // We can replace LoadField[Map](o) with map if is stable and either |
| 1959 // (a) o has type Constant(object) and map == object->map, or |
| 1960 // (b) o has type Class(map), |
| 1961 // and either |
| 1962 // (1) map cannot transition further, or |
| 1963 // (2) deoptimization is enabled and we can add a code dependency on the |
| 1964 // stability of map (to guard the Constant type information). |
| 1965 Handle<Map> object_map; |
| 1966 if (GetStableMapFromObjectType(object_type).ToHandle(&object_map)) { |
| 1967 if (object_map->CanTransition()) { |
| 1968 if (flags() & kDeoptimizationEnabled) { |
| 1969 dependencies()->AssumeMapStable(object_map); |
| 1970 } else { |
| 1971 return NoChange(); |
| 1972 } |
| 1973 } |
| 1974 Node* const value = jsgraph()->HeapConstant(object_map); |
| 1975 ReplaceWithValue(node, value); |
| 1976 return Replace(value); |
| 1977 } |
| 1978 } |
| 1979 return NoChange(); |
| 1980 } |
| 1981 |
1903 Reduction JSTypedLowering::ReduceNumberRoundop(Node* node) { | 1982 Reduction JSTypedLowering::ReduceNumberRoundop(Node* node) { |
1904 // TODO(bmeurer): Find a better home for this thing! | 1983 // TODO(bmeurer): Find a better home for this thing! |
1905 Node* const input = NodeProperties::GetValueInput(node, 0); | 1984 Node* const input = NodeProperties::GetValueInput(node, 0); |
1906 Type* const input_type = NodeProperties::GetType(input); | 1985 Type* const input_type = NodeProperties::GetType(input); |
1907 if (input_type->Is(type_cache_.kIntegerOrMinusZeroOrNaN)) { | 1986 if (input_type->Is(type_cache_.kIntegerOrMinusZeroOrNaN)) { |
1908 return Replace(input); | 1987 return Replace(input); |
1909 } | 1988 } |
1910 return NoChange(); | 1989 return NoChange(); |
1911 } | 1990 } |
1912 | 1991 |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2023 case IrOpcode::kJSForInStep: | 2102 case IrOpcode::kJSForInStep: |
2024 return ReduceJSForInStep(node); | 2103 return ReduceJSForInStep(node); |
2025 case IrOpcode::kJSGeneratorStore: | 2104 case IrOpcode::kJSGeneratorStore: |
2026 return ReduceJSGeneratorStore(node); | 2105 return ReduceJSGeneratorStore(node); |
2027 case IrOpcode::kJSGeneratorRestoreContinuation: | 2106 case IrOpcode::kJSGeneratorRestoreContinuation: |
2028 return ReduceJSGeneratorRestoreContinuation(node); | 2107 return ReduceJSGeneratorRestoreContinuation(node); |
2029 case IrOpcode::kJSGeneratorRestoreRegister: | 2108 case IrOpcode::kJSGeneratorRestoreRegister: |
2030 return ReduceJSGeneratorRestoreRegister(node); | 2109 return ReduceJSGeneratorRestoreRegister(node); |
2031 case IrOpcode::kSelect: | 2110 case IrOpcode::kSelect: |
2032 return ReduceSelect(node); | 2111 return ReduceSelect(node); |
| 2112 case IrOpcode::kCheckMaps: |
| 2113 return ReduceCheckMaps(node); |
2033 case IrOpcode::kCheckString: | 2114 case IrOpcode::kCheckString: |
2034 return ReduceCheckString(node); | 2115 return ReduceCheckString(node); |
2035 case IrOpcode::kNumberCeil: | 2116 case IrOpcode::kNumberCeil: |
2036 case IrOpcode::kNumberFloor: | 2117 case IrOpcode::kNumberFloor: |
2037 case IrOpcode::kNumberRound: | 2118 case IrOpcode::kNumberRound: |
2038 case IrOpcode::kNumberTrunc: | 2119 case IrOpcode::kNumberTrunc: |
2039 return ReduceNumberRoundop(node); | 2120 return ReduceNumberRoundop(node); |
| 2121 case IrOpcode::kLoadField: |
| 2122 return ReduceLoadField(node); |
2040 default: | 2123 default: |
2041 break; | 2124 break; |
2042 } | 2125 } |
2043 return NoChange(); | 2126 return NoChange(); |
2044 } | 2127 } |
2045 | 2128 |
2046 Node* JSTypedLowering::EmptyFrameState() { | 2129 Node* JSTypedLowering::EmptyFrameState() { |
2047 return graph()->NewNode( | 2130 return graph()->NewNode( |
2048 common()->FrameState(BailoutId::None(), OutputFrameStateCombine::Ignore(), | 2131 common()->FrameState(BailoutId::None(), OutputFrameStateCombine::Ignore(), |
2049 nullptr), | 2132 nullptr), |
(...skipping 29 matching lines...) Expand all Loading... |
2079 } | 2162 } |
2080 | 2163 |
2081 | 2164 |
2082 CompilationDependencies* JSTypedLowering::dependencies() const { | 2165 CompilationDependencies* JSTypedLowering::dependencies() const { |
2083 return dependencies_; | 2166 return dependencies_; |
2084 } | 2167 } |
2085 | 2168 |
2086 } // namespace compiler | 2169 } // namespace compiler |
2087 } // namespace internal | 2170 } // namespace internal |
2088 } // namespace v8 | 2171 } // namespace v8 |
OLD | NEW |