| 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.h" | 5 #include "src/compiler.h" |
| 6 | 6 |
| 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-operator.h" | 9 #include "src/compiler/js-operator.h" |
| 10 #include "src/compiler/js-type-feedback.h" | 10 #include "src/compiler/js-type-feedback.h" |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 | 107 |
| 108 | 108 |
| 109 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstSmi) { | 109 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstSmi) { |
| 110 const int kValue = 111; | 110 const int kValue = 111; |
| 111 const char* kName = "banana"; | 111 const char* kName = "banana"; |
| 112 SetGlobalProperty(kName, kValue); | 112 SetGlobalProperty(kName, kValue); |
| 113 | 113 |
| 114 Node* ret = ReturnLoadNamedFromGlobal( | 114 Node* ret = ReturnLoadNamedFromGlobal( |
| 115 kName, graph()->start(), graph()->start(), | 115 kName, graph()->start(), graph()->start(), |
| 116 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); | 116 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
| 117 graph()->SetEnd(graph()->NewNode(common()->End(), ret)); | 117 graph()->SetEnd(graph()->NewNode(common()->End(1), ret)); |
| 118 | 118 |
| 119 Reduction r = Reduce(ret->InputAt(0), | 119 Reduction r = Reduce(ret->InputAt(0), |
| 120 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); | 120 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
| 121 EXPECT_FALSE(r.Changed()); | 121 EXPECT_FALSE(r.Changed()); |
| 122 EXPECT_TRUE(dependencies()->IsEmpty()); | 122 EXPECT_TRUE(dependencies()->IsEmpty()); |
| 123 } | 123 } |
| 124 | 124 |
| 125 | 125 |
| 126 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstSmiWithDeoptimization) { | 126 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstSmiWithDeoptimization) { |
| 127 const int kValue = 111; | 127 const int kValue = 111; |
| 128 const char* kName = "banana"; | 128 const char* kName = "banana"; |
| 129 SetGlobalProperty(kName, kValue); | 129 SetGlobalProperty(kName, kValue); |
| 130 | 130 |
| 131 Node* ret = ReturnLoadNamedFromGlobal( | 131 Node* ret = ReturnLoadNamedFromGlobal( |
| 132 kName, graph()->start(), graph()->start(), | 132 kName, graph()->start(), graph()->start(), |
| 133 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); | 133 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
| 134 graph()->SetEnd(graph()->NewNode(common()->End(), ret)); | 134 graph()->SetEnd(graph()->NewNode(common()->End(1), ret)); |
| 135 | 135 |
| 136 Reduction r = Reduce(ret->InputAt(0), | 136 Reduction r = Reduce(ret->InputAt(0), |
| 137 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); | 137 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
| 138 | 138 |
| 139 // Check LoadNamed(global) => HeapConstant[kValue] | 139 // Check LoadNamed(global) => HeapConstant[kValue] |
| 140 ASSERT_TRUE(r.Changed()); | 140 ASSERT_TRUE(r.Changed()); |
| 141 EXPECT_THAT(r.replacement(), IsNumberConstant(kValue)); | 141 EXPECT_THAT(r.replacement(), IsNumberConstant(kValue)); |
| 142 | 142 |
| 143 EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), graph()->start(), | 143 EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), graph()->start(), |
| 144 graph()->start())); | 144 graph()->start())); |
| 145 EXPECT_THAT(graph()->end(), IsEnd(ret)); | 145 EXPECT_THAT(graph()->end(), IsEnd(ret)); |
| 146 | 146 |
| 147 EXPECT_FALSE(dependencies()->IsEmpty()); | 147 EXPECT_FALSE(dependencies()->IsEmpty()); |
| 148 dependencies()->Rollback(); | 148 dependencies()->Rollback(); |
| 149 } | 149 } |
| 150 | 150 |
| 151 | 151 |
| 152 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstNumber) { | 152 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstNumber) { |
| 153 const double kValue = -11.25; | 153 const double kValue = -11.25; |
| 154 const char* kName = "kiwi"; | 154 const char* kName = "kiwi"; |
| 155 SetGlobalProperty(kName, kValue); | 155 SetGlobalProperty(kName, kValue); |
| 156 | 156 |
| 157 Node* ret = ReturnLoadNamedFromGlobal( | 157 Node* ret = ReturnLoadNamedFromGlobal( |
| 158 kName, graph()->start(), graph()->start(), | 158 kName, graph()->start(), graph()->start(), |
| 159 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); | 159 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
| 160 graph()->SetEnd(graph()->NewNode(common()->End(), ret)); | 160 graph()->SetEnd(graph()->NewNode(common()->End(1), ret)); |
| 161 | 161 |
| 162 Reduction r = Reduce(ret->InputAt(0), | 162 Reduction r = Reduce(ret->InputAt(0), |
| 163 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); | 163 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
| 164 | 164 |
| 165 EXPECT_FALSE(r.Changed()); | 165 EXPECT_FALSE(r.Changed()); |
| 166 EXPECT_TRUE(dependencies()->IsEmpty()); | 166 EXPECT_TRUE(dependencies()->IsEmpty()); |
| 167 } | 167 } |
| 168 | 168 |
| 169 | 169 |
| 170 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstNumberWithDeoptimization) { | 170 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstNumberWithDeoptimization) { |
| 171 const double kValue = -11.25; | 171 const double kValue = -11.25; |
| 172 const char* kName = "kiwi"; | 172 const char* kName = "kiwi"; |
| 173 SetGlobalProperty(kName, kValue); | 173 SetGlobalProperty(kName, kValue); |
| 174 | 174 |
| 175 Node* ret = ReturnLoadNamedFromGlobal( | 175 Node* ret = ReturnLoadNamedFromGlobal( |
| 176 kName, graph()->start(), graph()->start(), | 176 kName, graph()->start(), graph()->start(), |
| 177 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); | 177 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
| 178 graph()->SetEnd(graph()->NewNode(common()->End(), ret)); | 178 graph()->SetEnd(graph()->NewNode(common()->End(1), ret)); |
| 179 | 179 |
| 180 Reduction r = Reduce(ret->InputAt(0), | 180 Reduction r = Reduce(ret->InputAt(0), |
| 181 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); | 181 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
| 182 | 182 |
| 183 // Check LoadNamed(global) => HeapConstant[kValue] | 183 // Check LoadNamed(global) => HeapConstant[kValue] |
| 184 ASSERT_TRUE(r.Changed()); | 184 ASSERT_TRUE(r.Changed()); |
| 185 EXPECT_THAT(r.replacement(), IsNumberConstant(kValue)); | 185 EXPECT_THAT(r.replacement(), IsNumberConstant(kValue)); |
| 186 | 186 |
| 187 EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), graph()->start(), | 187 EXPECT_THAT(ret, IsReturn(IsNumberConstant(kValue), graph()->start(), |
| 188 graph()->start())); | 188 graph()->start())); |
| 189 EXPECT_THAT(graph()->end(), IsEnd(ret)); | 189 EXPECT_THAT(graph()->end(), IsEnd(ret)); |
| 190 | 190 |
| 191 EXPECT_FALSE(dependencies()->IsEmpty()); | 191 EXPECT_FALSE(dependencies()->IsEmpty()); |
| 192 } | 192 } |
| 193 | 193 |
| 194 | 194 |
| 195 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstString) { | 195 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstString) { |
| 196 Unique<HeapObject> kValue = Unique<HeapObject>::CreateImmovable( | 196 Unique<HeapObject> kValue = Unique<HeapObject>::CreateImmovable( |
| 197 isolate()->factory()->undefined_string()); | 197 isolate()->factory()->undefined_string()); |
| 198 const char* kName = "mango"; | 198 const char* kName = "mango"; |
| 199 SetGlobalProperty(kName, kValue.handle()); | 199 SetGlobalProperty(kName, kValue.handle()); |
| 200 | 200 |
| 201 Node* ret = ReturnLoadNamedFromGlobal( | 201 Node* ret = ReturnLoadNamedFromGlobal( |
| 202 kName, graph()->start(), graph()->start(), | 202 kName, graph()->start(), graph()->start(), |
| 203 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); | 203 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
| 204 graph()->SetEnd(graph()->NewNode(common()->End(), ret)); | 204 graph()->SetEnd(graph()->NewNode(common()->End(1), ret)); |
| 205 | 205 |
| 206 Reduction r = Reduce(ret->InputAt(0), | 206 Reduction r = Reduce(ret->InputAt(0), |
| 207 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); | 207 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
| 208 ASSERT_FALSE(r.Changed()); | 208 ASSERT_FALSE(r.Changed()); |
| 209 EXPECT_TRUE(dependencies()->IsEmpty()); | 209 EXPECT_TRUE(dependencies()->IsEmpty()); |
| 210 } | 210 } |
| 211 | 211 |
| 212 | 212 |
| 213 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstStringWithDeoptimization) { | 213 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalConstStringWithDeoptimization) { |
| 214 Unique<HeapObject> kValue = Unique<HeapObject>::CreateImmovable( | 214 Unique<HeapObject> kValue = Unique<HeapObject>::CreateImmovable( |
| 215 isolate()->factory()->undefined_string()); | 215 isolate()->factory()->undefined_string()); |
| 216 const char* kName = "mango"; | 216 const char* kName = "mango"; |
| 217 SetGlobalProperty(kName, kValue.handle()); | 217 SetGlobalProperty(kName, kValue.handle()); |
| 218 | 218 |
| 219 Node* ret = ReturnLoadNamedFromGlobal( | 219 Node* ret = ReturnLoadNamedFromGlobal( |
| 220 kName, graph()->start(), graph()->start(), | 220 kName, graph()->start(), graph()->start(), |
| 221 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); | 221 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
| 222 graph()->SetEnd(graph()->NewNode(common()->End(), ret)); | 222 graph()->SetEnd(graph()->NewNode(common()->End(1), ret)); |
| 223 | 223 |
| 224 Reduction r = Reduce(ret->InputAt(0), | 224 Reduction r = Reduce(ret->InputAt(0), |
| 225 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); | 225 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
| 226 | 226 |
| 227 // Check LoadNamed(global) => HeapConstant[kValue] | 227 // Check LoadNamed(global) => HeapConstant[kValue] |
| 228 ASSERT_TRUE(r.Changed()); | 228 ASSERT_TRUE(r.Changed()); |
| 229 EXPECT_THAT(r.replacement(), IsHeapConstant(kValue)); | 229 EXPECT_THAT(r.replacement(), IsHeapConstant(kValue)); |
| 230 | 230 |
| 231 EXPECT_THAT(ret, IsReturn(IsHeapConstant(kValue), graph()->start(), | 231 EXPECT_THAT(ret, IsReturn(IsHeapConstant(kValue), graph()->start(), |
| 232 graph()->start())); | 232 graph()->start())); |
| 233 EXPECT_THAT(graph()->end(), IsEnd(ret)); | 233 EXPECT_THAT(graph()->end(), IsEnd(ret)); |
| 234 | 234 |
| 235 EXPECT_FALSE(dependencies()->IsEmpty()); | 235 EXPECT_FALSE(dependencies()->IsEmpty()); |
| 236 dependencies()->Rollback(); | 236 dependencies()->Rollback(); |
| 237 } | 237 } |
| 238 | 238 |
| 239 | 239 |
| 240 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCellSmi) { | 240 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCellSmi) { |
| 241 const char* kName = "melon"; | 241 const char* kName = "melon"; |
| 242 SetGlobalProperty(kName, 123); | 242 SetGlobalProperty(kName, 123); |
| 243 SetGlobalProperty(kName, 124); | 243 SetGlobalProperty(kName, 124); |
| 244 | 244 |
| 245 Node* ret = ReturnLoadNamedFromGlobal( | 245 Node* ret = ReturnLoadNamedFromGlobal( |
| 246 kName, graph()->start(), graph()->start(), | 246 kName, graph()->start(), graph()->start(), |
| 247 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); | 247 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
| 248 graph()->SetEnd(graph()->NewNode(common()->End(), ret)); | 248 graph()->SetEnd(graph()->NewNode(common()->End(1), ret)); |
| 249 | 249 |
| 250 Reduction r = Reduce(ret->InputAt(0), | 250 Reduction r = Reduce(ret->InputAt(0), |
| 251 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); | 251 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
| 252 ASSERT_FALSE(r.Changed()); | 252 ASSERT_FALSE(r.Changed()); |
| 253 EXPECT_TRUE(dependencies()->IsEmpty()); | 253 EXPECT_TRUE(dependencies()->IsEmpty()); |
| 254 } | 254 } |
| 255 | 255 |
| 256 | 256 |
| 257 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCellSmiWithDeoptimization) { | 257 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCellSmiWithDeoptimization) { |
| 258 const char* kName = "melon"; | 258 const char* kName = "melon"; |
| 259 SetGlobalProperty(kName, 123); | 259 SetGlobalProperty(kName, 123); |
| 260 SetGlobalProperty(kName, 124); | 260 SetGlobalProperty(kName, 124); |
| 261 | 261 |
| 262 Node* ret = ReturnLoadNamedFromGlobal( | 262 Node* ret = ReturnLoadNamedFromGlobal( |
| 263 kName, graph()->start(), graph()->start(), | 263 kName, graph()->start(), graph()->start(), |
| 264 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); | 264 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
| 265 graph()->SetEnd(graph()->NewNode(common()->End(), ret)); | 265 graph()->SetEnd(graph()->NewNode(common()->End(1), ret)); |
| 266 | 266 |
| 267 Reduction r = Reduce(ret->InputAt(0), | 267 Reduction r = Reduce(ret->InputAt(0), |
| 268 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); | 268 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
| 269 | 269 |
| 270 // Check LoadNamed(global) => LoadField[PropertyCell::value](cell) | 270 // Check LoadNamed(global) => LoadField[PropertyCell::value](cell) |
| 271 ASSERT_TRUE(r.Changed()); | 271 ASSERT_TRUE(r.Changed()); |
| 272 FieldAccess access = AccessBuilder::ForPropertyCellValue(); | 272 FieldAccess access = AccessBuilder::ForPropertyCellValue(); |
| 273 Capture<Node*> cell_capture; | 273 Capture<Node*> cell_capture; |
| 274 Matcher<Node*> load_field_match = IsLoadField( | 274 Matcher<Node*> load_field_match = IsLoadField( |
| 275 access, CaptureEq(&cell_capture), graph()->start(), graph()->start()); | 275 access, CaptureEq(&cell_capture), graph()->start(), graph()->start()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 289 | 289 |
| 290 | 290 |
| 291 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCellString) { | 291 TEST_F(JSTypeFeedbackTest, JSLoadNamedGlobalPropertyCellString) { |
| 292 const char* kName = "pineapple"; | 292 const char* kName = "pineapple"; |
| 293 SetGlobalProperty(kName, isolate()->factory()->undefined_string()); | 293 SetGlobalProperty(kName, isolate()->factory()->undefined_string()); |
| 294 SetGlobalProperty(kName, isolate()->factory()->undefined_value()); | 294 SetGlobalProperty(kName, isolate()->factory()->undefined_value()); |
| 295 | 295 |
| 296 Node* ret = ReturnLoadNamedFromGlobal( | 296 Node* ret = ReturnLoadNamedFromGlobal( |
| 297 kName, graph()->start(), graph()->start(), | 297 kName, graph()->start(), graph()->start(), |
| 298 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); | 298 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
| 299 graph()->SetEnd(graph()->NewNode(common()->End(), ret)); | 299 graph()->SetEnd(graph()->NewNode(common()->End(1), ret)); |
| 300 | 300 |
| 301 Reduction r = Reduce(ret->InputAt(0), | 301 Reduction r = Reduce(ret->InputAt(0), |
| 302 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); | 302 JSTypeFeedbackSpecializer::kDeoptimizationDisabled); |
| 303 ASSERT_FALSE(r.Changed()); | 303 ASSERT_FALSE(r.Changed()); |
| 304 EXPECT_TRUE(dependencies()->IsEmpty()); | 304 EXPECT_TRUE(dependencies()->IsEmpty()); |
| 305 } | 305 } |
| 306 | 306 |
| 307 | 307 |
| 308 TEST_F(JSTypeFeedbackTest, | 308 TEST_F(JSTypeFeedbackTest, |
| 309 JSLoadNamedGlobalPropertyCellStringWithDeoptimization) { | 309 JSLoadNamedGlobalPropertyCellStringWithDeoptimization) { |
| 310 const char* kName = "pineapple"; | 310 const char* kName = "pineapple"; |
| 311 SetGlobalProperty(kName, isolate()->factory()->undefined_string()); | 311 SetGlobalProperty(kName, isolate()->factory()->undefined_string()); |
| 312 SetGlobalProperty(kName, isolate()->factory()->undefined_value()); | 312 SetGlobalProperty(kName, isolate()->factory()->undefined_value()); |
| 313 | 313 |
| 314 Node* ret = ReturnLoadNamedFromGlobal( | 314 Node* ret = ReturnLoadNamedFromGlobal( |
| 315 kName, graph()->start(), graph()->start(), | 315 kName, graph()->start(), graph()->start(), |
| 316 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); | 316 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
| 317 graph()->SetEnd(graph()->NewNode(common()->End(), ret)); | 317 graph()->SetEnd(graph()->NewNode(common()->End(1), ret)); |
| 318 | 318 |
| 319 Reduction r = Reduce(ret->InputAt(0), | 319 Reduction r = Reduce(ret->InputAt(0), |
| 320 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); | 320 JSTypeFeedbackSpecializer::kDeoptimizationEnabled); |
| 321 | 321 |
| 322 // Check LoadNamed(global) => LoadField[PropertyCell::value](cell) | 322 // Check LoadNamed(global) => LoadField[PropertyCell::value](cell) |
| 323 ASSERT_TRUE(r.Changed()); | 323 ASSERT_TRUE(r.Changed()); |
| 324 FieldAccess access = AccessBuilder::ForPropertyCellValue(); | 324 FieldAccess access = AccessBuilder::ForPropertyCellValue(); |
| 325 Capture<Node*> cell_capture; | 325 Capture<Node*> cell_capture; |
| 326 Matcher<Node*> load_field_match = IsLoadField( | 326 Matcher<Node*> load_field_match = IsLoadField( |
| 327 access, CaptureEq(&cell_capture), graph()->start(), graph()->start()); | 327 access, CaptureEq(&cell_capture), graph()->start(), graph()->start()); |
| 328 EXPECT_THAT(r.replacement(), load_field_match); | 328 EXPECT_THAT(r.replacement(), load_field_match); |
| 329 | 329 |
| 330 HeapObjectMatcher<PropertyCell> cell(cell_capture.value()); | 330 HeapObjectMatcher<PropertyCell> cell(cell_capture.value()); |
| 331 EXPECT_TRUE(cell.HasValue()); | 331 EXPECT_TRUE(cell.HasValue()); |
| 332 EXPECT_TRUE(cell.Value().handle()->IsPropertyCell()); | 332 EXPECT_TRUE(cell.Value().handle()->IsPropertyCell()); |
| 333 | 333 |
| 334 EXPECT_THAT(ret, | 334 EXPECT_THAT(ret, |
| 335 IsReturn(load_field_match, load_field_match, graph()->start())); | 335 IsReturn(load_field_match, load_field_match, graph()->start())); |
| 336 EXPECT_THAT(graph()->end(), IsEnd(ret)); | 336 EXPECT_THAT(graph()->end(), IsEnd(ret)); |
| 337 | 337 |
| 338 EXPECT_FALSE(dependencies()->IsEmpty()); | 338 EXPECT_FALSE(dependencies()->IsEmpty()); |
| 339 dependencies()->Rollback(); | 339 dependencies()->Rollback(); |
| 340 } | 340 } |
| 341 | 341 |
| 342 } // namespace compiler | 342 } // namespace compiler |
| 343 } // namespace internal | 343 } // namespace internal |
| 344 } // namespace v8 | 344 } // namespace v8 |
| OLD | NEW |