| 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 "test/unittests/compiler/instruction-selector-unittest.h" | 5 #include "test/unittests/compiler/instruction-selector-unittest.h" |
| 6 | 6 |
| 7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
| 8 #include "src/compiler/graph.h" | 8 #include "src/compiler/graph.h" |
| 9 #include "src/compiler/schedule.h" | 9 #include "src/compiler/schedule.h" |
| 10 #include "src/flags.h" | 10 #include "src/flags.h" |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 Handle<SharedFunctionInfo>(), CALL_MAINTAINS_NATIVE_CONTEXT); | 151 Handle<SharedFunctionInfo>(), CALL_MAINTAINS_NATIVE_CONTEXT); |
| 152 } | 152 } |
| 153 | 153 |
| 154 | 154 |
| 155 // ----------------------------------------------------------------------------- | 155 // ----------------------------------------------------------------------------- |
| 156 // Return. | 156 // Return. |
| 157 | 157 |
| 158 | 158 |
| 159 TARGET_TEST_F(InstructionSelectorTest, ReturnFloat32Constant) { | 159 TARGET_TEST_F(InstructionSelectorTest, ReturnFloat32Constant) { |
| 160 const float kValue = 4.2f; | 160 const float kValue = 4.2f; |
| 161 StreamBuilder m(this, kMachFloat32); | 161 StreamBuilder m(this, MachineType::Float32()); |
| 162 m.Return(m.Float32Constant(kValue)); | 162 m.Return(m.Float32Constant(kValue)); |
| 163 Stream s = m.Build(kAllInstructions); | 163 Stream s = m.Build(kAllInstructions); |
| 164 ASSERT_EQ(3U, s.size()); | 164 ASSERT_EQ(3U, s.size()); |
| 165 EXPECT_EQ(kArchNop, s[0]->arch_opcode()); | 165 EXPECT_EQ(kArchNop, s[0]->arch_opcode()); |
| 166 ASSERT_EQ(InstructionOperand::CONSTANT, s[0]->OutputAt(0)->kind()); | 166 ASSERT_EQ(InstructionOperand::CONSTANT, s[0]->OutputAt(0)->kind()); |
| 167 EXPECT_FLOAT_EQ(kValue, s.ToFloat32(s[0]->OutputAt(0))); | 167 EXPECT_FLOAT_EQ(kValue, s.ToFloat32(s[0]->OutputAt(0))); |
| 168 EXPECT_EQ(kArchRet, s[1]->arch_opcode()); | 168 EXPECT_EQ(kArchRet, s[1]->arch_opcode()); |
| 169 EXPECT_EQ(1U, s[1]->InputCount()); | 169 EXPECT_EQ(1U, s[1]->InputCount()); |
| 170 } | 170 } |
| 171 | 171 |
| 172 | 172 |
| 173 TARGET_TEST_F(InstructionSelectorTest, ReturnParameter) { | 173 TARGET_TEST_F(InstructionSelectorTest, ReturnParameter) { |
| 174 StreamBuilder m(this, kMachInt32, kMachInt32); | 174 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
| 175 m.Return(m.Parameter(0)); | 175 m.Return(m.Parameter(0)); |
| 176 Stream s = m.Build(kAllInstructions); | 176 Stream s = m.Build(kAllInstructions); |
| 177 ASSERT_EQ(3U, s.size()); | 177 ASSERT_EQ(3U, s.size()); |
| 178 EXPECT_EQ(kArchNop, s[0]->arch_opcode()); | 178 EXPECT_EQ(kArchNop, s[0]->arch_opcode()); |
| 179 ASSERT_EQ(1U, s[0]->OutputCount()); | 179 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 180 EXPECT_EQ(kArchRet, s[1]->arch_opcode()); | 180 EXPECT_EQ(kArchRet, s[1]->arch_opcode()); |
| 181 EXPECT_EQ(1U, s[1]->InputCount()); | 181 EXPECT_EQ(1U, s[1]->InputCount()); |
| 182 } | 182 } |
| 183 | 183 |
| 184 | 184 |
| 185 TARGET_TEST_F(InstructionSelectorTest, ReturnZero) { | 185 TARGET_TEST_F(InstructionSelectorTest, ReturnZero) { |
| 186 StreamBuilder m(this, kMachInt32); | 186 StreamBuilder m(this, MachineType::Int32()); |
| 187 m.Return(m.Int32Constant(0)); | 187 m.Return(m.Int32Constant(0)); |
| 188 Stream s = m.Build(kAllInstructions); | 188 Stream s = m.Build(kAllInstructions); |
| 189 ASSERT_EQ(3U, s.size()); | 189 ASSERT_EQ(3U, s.size()); |
| 190 EXPECT_EQ(kArchNop, s[0]->arch_opcode()); | 190 EXPECT_EQ(kArchNop, s[0]->arch_opcode()); |
| 191 ASSERT_EQ(1U, s[0]->OutputCount()); | 191 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 192 EXPECT_EQ(InstructionOperand::CONSTANT, s[0]->OutputAt(0)->kind()); | 192 EXPECT_EQ(InstructionOperand::CONSTANT, s[0]->OutputAt(0)->kind()); |
| 193 EXPECT_EQ(0, s.ToInt32(s[0]->OutputAt(0))); | 193 EXPECT_EQ(0, s.ToInt32(s[0]->OutputAt(0))); |
| 194 EXPECT_EQ(kArchRet, s[1]->arch_opcode()); | 194 EXPECT_EQ(kArchRet, s[1]->arch_opcode()); |
| 195 EXPECT_EQ(1U, s[1]->InputCount()); | 195 EXPECT_EQ(1U, s[1]->InputCount()); |
| 196 } | 196 } |
| 197 | 197 |
| 198 | 198 |
| 199 // ----------------------------------------------------------------------------- | 199 // ----------------------------------------------------------------------------- |
| 200 // Conversions. | 200 // Conversions. |
| 201 | 201 |
| 202 | 202 |
| 203 TARGET_TEST_F(InstructionSelectorTest, TruncateFloat64ToInt32WithParameter) { | 203 TARGET_TEST_F(InstructionSelectorTest, TruncateFloat64ToInt32WithParameter) { |
| 204 StreamBuilder m(this, kMachInt32, kMachFloat64); | 204 StreamBuilder m(this, MachineType::Int32(), MachineType::Float64()); |
| 205 m.Return( | 205 m.Return( |
| 206 m.TruncateFloat64ToInt32(TruncationMode::kJavaScript, m.Parameter(0))); | 206 m.TruncateFloat64ToInt32(TruncationMode::kJavaScript, m.Parameter(0))); |
| 207 Stream s = m.Build(kAllInstructions); | 207 Stream s = m.Build(kAllInstructions); |
| 208 ASSERT_EQ(4U, s.size()); | 208 ASSERT_EQ(4U, s.size()); |
| 209 EXPECT_EQ(kArchNop, s[0]->arch_opcode()); | 209 EXPECT_EQ(kArchNop, s[0]->arch_opcode()); |
| 210 EXPECT_EQ(kArchTruncateDoubleToI, s[1]->arch_opcode()); | 210 EXPECT_EQ(kArchTruncateDoubleToI, s[1]->arch_opcode()); |
| 211 EXPECT_EQ(1U, s[1]->InputCount()); | 211 EXPECT_EQ(1U, s[1]->InputCount()); |
| 212 EXPECT_EQ(1U, s[1]->OutputCount()); | 212 EXPECT_EQ(1U, s[1]->OutputCount()); |
| 213 EXPECT_EQ(kArchRet, s[2]->arch_opcode()); | 213 EXPECT_EQ(kArchRet, s[2]->arch_opcode()); |
| 214 } | 214 } |
| 215 | 215 |
| 216 | 216 |
| 217 // ----------------------------------------------------------------------------- | 217 // ----------------------------------------------------------------------------- |
| 218 // Parameters. | 218 // Parameters. |
| 219 | 219 |
| 220 | 220 |
| 221 TARGET_TEST_F(InstructionSelectorTest, DoubleParameter) { | 221 TARGET_TEST_F(InstructionSelectorTest, DoubleParameter) { |
| 222 StreamBuilder m(this, kMachFloat64, kMachFloat64); | 222 StreamBuilder m(this, MachineType::Float64(), MachineType::Float64()); |
| 223 Node* param = m.Parameter(0); | 223 Node* param = m.Parameter(0); |
| 224 m.Return(param); | 224 m.Return(param); |
| 225 Stream s = m.Build(kAllInstructions); | 225 Stream s = m.Build(kAllInstructions); |
| 226 EXPECT_TRUE(s.IsDouble(param)); | 226 EXPECT_TRUE(s.IsDouble(param)); |
| 227 } | 227 } |
| 228 | 228 |
| 229 | 229 |
| 230 TARGET_TEST_F(InstructionSelectorTest, ReferenceParameter) { | 230 TARGET_TEST_F(InstructionSelectorTest, ReferenceParameter) { |
| 231 StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged); | 231 StreamBuilder m(this, MachineType::AnyTagged(), MachineType::AnyTagged()); |
| 232 Node* param = m.Parameter(0); | 232 Node* param = m.Parameter(0); |
| 233 m.Return(param); | 233 m.Return(param); |
| 234 Stream s = m.Build(kAllInstructions); | 234 Stream s = m.Build(kAllInstructions); |
| 235 EXPECT_TRUE(s.IsReference(param)); | 235 EXPECT_TRUE(s.IsReference(param)); |
| 236 } | 236 } |
| 237 | 237 |
| 238 | 238 |
| 239 // ----------------------------------------------------------------------------- | 239 // ----------------------------------------------------------------------------- |
| 240 // FinishRegion. | 240 // FinishRegion. |
| 241 | 241 |
| 242 | 242 |
| 243 TARGET_TEST_F(InstructionSelectorTest, FinishRegion) { | 243 TARGET_TEST_F(InstructionSelectorTest, FinishRegion) { |
| 244 StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged); | 244 StreamBuilder m(this, MachineType::AnyTagged(), MachineType::AnyTagged()); |
| 245 Node* param = m.Parameter(0); | 245 Node* param = m.Parameter(0); |
| 246 Node* finish = | 246 Node* finish = |
| 247 m.AddNode(m.common()->FinishRegion(), param, m.graph()->start()); | 247 m.AddNode(m.common()->FinishRegion(), param, m.graph()->start()); |
| 248 m.Return(finish); | 248 m.Return(finish); |
| 249 Stream s = m.Build(kAllInstructions); | 249 Stream s = m.Build(kAllInstructions); |
| 250 ASSERT_EQ(4U, s.size()); | 250 ASSERT_EQ(4U, s.size()); |
| 251 EXPECT_EQ(kArchNop, s[0]->arch_opcode()); | 251 EXPECT_EQ(kArchNop, s[0]->arch_opcode()); |
| 252 ASSERT_EQ(1U, s[0]->OutputCount()); | 252 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 253 ASSERT_TRUE(s[0]->Output()->IsUnallocated()); | 253 ASSERT_TRUE(s[0]->Output()->IsUnallocated()); |
| 254 EXPECT_EQ(s.ToVreg(param), s.ToVreg(s[0]->Output())); | 254 EXPECT_EQ(s.ToVreg(param), s.ToVreg(s[0]->Output())); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 277 StreamBuilder m(this, type, type, type); | 277 StreamBuilder m(this, type, type, type); |
| 278 Node* param0 = m.Parameter(0); | 278 Node* param0 = m.Parameter(0); |
| 279 Node* param1 = m.Parameter(1); | 279 Node* param1 = m.Parameter(1); |
| 280 RawMachineLabel a, b, c; | 280 RawMachineLabel a, b, c; |
| 281 m.Branch(m.Int32Constant(0), &a, &b); | 281 m.Branch(m.Int32Constant(0), &a, &b); |
| 282 m.Bind(&a); | 282 m.Bind(&a); |
| 283 m.Goto(&c); | 283 m.Goto(&c); |
| 284 m.Bind(&b); | 284 m.Bind(&b); |
| 285 m.Goto(&c); | 285 m.Goto(&c); |
| 286 m.Bind(&c); | 286 m.Bind(&c); |
| 287 Node* phi = m.Phi(type, param0, param1); | 287 Node* phi = m.Phi(type.representation(), param0, param1); |
| 288 m.Return(phi); | 288 m.Return(phi); |
| 289 Stream s = m.Build(kAllInstructions); | 289 Stream s = m.Build(kAllInstructions); |
| 290 EXPECT_EQ(s.IsDouble(phi), s.IsDouble(param0)); | 290 EXPECT_EQ(s.IsDouble(phi), s.IsDouble(param0)); |
| 291 EXPECT_EQ(s.IsDouble(phi), s.IsDouble(param1)); | 291 EXPECT_EQ(s.IsDouble(phi), s.IsDouble(param1)); |
| 292 } | 292 } |
| 293 | 293 |
| 294 | 294 |
| 295 TARGET_TEST_P(InstructionSelectorPhiTest, Referenceness) { | 295 TARGET_TEST_P(InstructionSelectorPhiTest, Referenceness) { |
| 296 const MachineType type = GetParam(); | 296 const MachineType type = GetParam(); |
| 297 StreamBuilder m(this, type, type, type); | 297 StreamBuilder m(this, type, type, type); |
| 298 Node* param0 = m.Parameter(0); | 298 Node* param0 = m.Parameter(0); |
| 299 Node* param1 = m.Parameter(1); | 299 Node* param1 = m.Parameter(1); |
| 300 RawMachineLabel a, b, c; | 300 RawMachineLabel a, b, c; |
| 301 m.Branch(m.Int32Constant(1), &a, &b); | 301 m.Branch(m.Int32Constant(1), &a, &b); |
| 302 m.Bind(&a); | 302 m.Bind(&a); |
| 303 m.Goto(&c); | 303 m.Goto(&c); |
| 304 m.Bind(&b); | 304 m.Bind(&b); |
| 305 m.Goto(&c); | 305 m.Goto(&c); |
| 306 m.Bind(&c); | 306 m.Bind(&c); |
| 307 Node* phi = m.Phi(type, param0, param1); | 307 Node* phi = m.Phi(type.representation(), param0, param1); |
| 308 m.Return(phi); | 308 m.Return(phi); |
| 309 Stream s = m.Build(kAllInstructions); | 309 Stream s = m.Build(kAllInstructions); |
| 310 EXPECT_EQ(s.IsReference(phi), s.IsReference(param0)); | 310 EXPECT_EQ(s.IsReference(phi), s.IsReference(param0)); |
| 311 EXPECT_EQ(s.IsReference(phi), s.IsReference(param1)); | 311 EXPECT_EQ(s.IsReference(phi), s.IsReference(param1)); |
| 312 } | 312 } |
| 313 | 313 |
| 314 | 314 |
| 315 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorPhiTest, | 315 INSTANTIATE_TEST_CASE_P( |
| 316 ::testing::Values(kMachFloat64, kMachInt8, kMachUint8, | 316 InstructionSelectorTest, InstructionSelectorPhiTest, |
| 317 kMachInt16, kMachUint16, kMachInt32, | 317 ::testing::Values(MachineType::Float64(), MachineType::Int8(), |
| 318 kMachUint32, kMachInt64, kMachUint64, | 318 MachineType::Uint8(), MachineType::Int16(), |
| 319 kMachPtr, kMachAnyTagged)); | 319 MachineType::Uint16(), MachineType::Int32(), |
| 320 MachineType::Uint32(), MachineType::Int64(), |
| 321 MachineType::Uint64(), MachineType::Pointer(), |
| 322 MachineType::AnyTagged())); |
| 320 | 323 |
| 321 | 324 |
| 322 // ----------------------------------------------------------------------------- | 325 // ----------------------------------------------------------------------------- |
| 323 // ValueEffect. | 326 // ValueEffect. |
| 324 | 327 |
| 325 | 328 |
| 326 TARGET_TEST_F(InstructionSelectorTest, ValueEffect) { | 329 TARGET_TEST_F(InstructionSelectorTest, ValueEffect) { |
| 327 StreamBuilder m1(this, kMachInt32, kMachPtr); | 330 StreamBuilder m1(this, MachineType::Int32(), MachineType::Pointer()); |
| 328 Node* p1 = m1.Parameter(0); | 331 Node* p1 = m1.Parameter(0); |
| 329 m1.Return(m1.Load(kMachInt32, p1, m1.Int32Constant(0))); | 332 m1.Return(m1.Load(MachineType::Int32(), p1, m1.Int32Constant(0))); |
| 330 Stream s1 = m1.Build(kAllInstructions); | 333 Stream s1 = m1.Build(kAllInstructions); |
| 331 StreamBuilder m2(this, kMachInt32, kMachPtr); | 334 StreamBuilder m2(this, MachineType::Int32(), MachineType::Pointer()); |
| 332 Node* p2 = m2.Parameter(0); | 335 Node* p2 = m2.Parameter(0); |
| 333 m2.Return( | 336 m2.Return(m2.AddNode( |
| 334 m2.AddNode(m2.machine()->Load(kMachInt32), p2, m2.Int32Constant(0), | 337 m2.machine()->Load(MachineType::Int32()), p2, m2.Int32Constant(0), |
| 335 m2.AddNode(m2.common()->BeginRegion(), m2.graph()->start()))); | 338 m2.AddNode(m2.common()->BeginRegion(), m2.graph()->start()))); |
| 336 Stream s2 = m2.Build(kAllInstructions); | 339 Stream s2 = m2.Build(kAllInstructions); |
| 337 EXPECT_LE(3U, s1.size()); | 340 EXPECT_LE(3U, s1.size()); |
| 338 ASSERT_EQ(s1.size(), s2.size()); | 341 ASSERT_EQ(s1.size(), s2.size()); |
| 339 TRACED_FORRANGE(size_t, i, 0, s1.size() - 1) { | 342 TRACED_FORRANGE(size_t, i, 0, s1.size() - 1) { |
| 340 const Instruction* i1 = s1[i]; | 343 const Instruction* i1 = s1[i]; |
| 341 const Instruction* i2 = s2[i]; | 344 const Instruction* i2 = s2[i]; |
| 342 EXPECT_EQ(i1->arch_opcode(), i2->arch_opcode()); | 345 EXPECT_EQ(i1->arch_opcode(), i2->arch_opcode()); |
| 343 EXPECT_EQ(i1->InputCount(), i2->InputCount()); | 346 EXPECT_EQ(i1->InputCount(), i2->InputCount()); |
| 344 EXPECT_EQ(i1->OutputCount(), i2->OutputCount()); | 347 EXPECT_EQ(i1->OutputCount(), i2->OutputCount()); |
| 345 } | 348 } |
| 346 } | 349 } |
| 347 | 350 |
| 348 | 351 |
| 349 // ----------------------------------------------------------------------------- | 352 // ----------------------------------------------------------------------------- |
| 350 // Calls with deoptimization. | 353 // Calls with deoptimization. |
| 351 | 354 |
| 352 | 355 |
| 353 TARGET_TEST_F(InstructionSelectorTest, CallJSFunctionWithDeopt) { | 356 TARGET_TEST_F(InstructionSelectorTest, CallJSFunctionWithDeopt) { |
| 354 StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged, kMachAnyTagged, | 357 StreamBuilder m(this, MachineType::AnyTagged(), MachineType::AnyTagged(), |
| 355 kMachAnyTagged); | 358 MachineType::AnyTagged(), MachineType::AnyTagged()); |
| 356 | 359 |
| 357 BailoutId bailout_id(42); | 360 BailoutId bailout_id(42); |
| 358 | 361 |
| 359 Node* function_node = m.Parameter(0); | 362 Node* function_node = m.Parameter(0); |
| 360 Node* receiver = m.Parameter(1); | 363 Node* receiver = m.Parameter(1); |
| 361 Node* context = m.Parameter(2); | 364 Node* context = m.Parameter(2); |
| 362 | 365 |
| 363 ZoneVector<MachineType> int32_type(1, kMachInt32, zone()); | 366 ZoneVector<MachineType> int32_type(1, MachineType::Int32(), zone()); |
| 364 ZoneVector<MachineType> empty_types(zone()); | 367 ZoneVector<MachineType> empty_types(zone()); |
| 365 | 368 |
| 366 CallDescriptor* descriptor = Linkage::GetJSCallDescriptor( | 369 CallDescriptor* descriptor = Linkage::GetJSCallDescriptor( |
| 367 zone(), false, 1, CallDescriptor::kNeedsFrameState); | 370 zone(), false, 1, CallDescriptor::kNeedsFrameState); |
| 368 | 371 |
| 369 // Build frame state for the state before the call. | 372 // Build frame state for the state before the call. |
| 370 Node* parameters = | 373 Node* parameters = |
| 371 m.AddNode(m.common()->TypedStateValues(&int32_type), m.Int32Constant(1)); | 374 m.AddNode(m.common()->TypedStateValues(&int32_type), m.Int32Constant(1)); |
| 372 Node* locals = m.AddNode(m.common()->TypedStateValues(&empty_types)); | 375 Node* locals = m.AddNode(m.common()->TypedStateValues(&empty_types)); |
| 373 Node* stack = m.AddNode(m.common()->TypedStateValues(&empty_types)); | 376 Node* stack = m.AddNode(m.common()->TypedStateValues(&empty_types)); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 395 ASSERT_EQ(index + 2, s.size()); | 398 ASSERT_EQ(index + 2, s.size()); |
| 396 | 399 |
| 397 EXPECT_EQ(kArchCallJSFunction, s[index++]->arch_opcode()); | 400 EXPECT_EQ(kArchCallJSFunction, s[index++]->arch_opcode()); |
| 398 EXPECT_EQ(kArchRet, s[index++]->arch_opcode()); | 401 EXPECT_EQ(kArchRet, s[index++]->arch_opcode()); |
| 399 | 402 |
| 400 // TODO(jarin) Check deoptimization table. | 403 // TODO(jarin) Check deoptimization table. |
| 401 } | 404 } |
| 402 | 405 |
| 403 | 406 |
| 404 TARGET_TEST_F(InstructionSelectorTest, CallStubWithDeopt) { | 407 TARGET_TEST_F(InstructionSelectorTest, CallStubWithDeopt) { |
| 405 StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged, kMachAnyTagged, | 408 StreamBuilder m(this, MachineType::AnyTagged(), MachineType::AnyTagged(), |
| 406 kMachAnyTagged); | 409 MachineType::AnyTagged(), MachineType::AnyTagged()); |
| 407 | 410 |
| 408 BailoutId bailout_id_before(42); | 411 BailoutId bailout_id_before(42); |
| 409 | 412 |
| 410 // Some arguments for the call node. | 413 // Some arguments for the call node. |
| 411 Node* function_node = m.Parameter(0); | 414 Node* function_node = m.Parameter(0); |
| 412 Node* receiver = m.Parameter(1); | 415 Node* receiver = m.Parameter(1); |
| 413 Node* context = m.Int32Constant(1); // Context is ignored. | 416 Node* context = m.Int32Constant(1); // Context is ignored. |
| 414 | 417 |
| 415 ZoneVector<MachineType> int32_type(1, kMachInt32, zone()); | 418 ZoneVector<MachineType> int32_type(1, MachineType::Int32(), zone()); |
| 416 ZoneVector<MachineType> float64_type(1, kMachFloat64, zone()); | 419 ZoneVector<MachineType> float64_type(1, MachineType::Float64(), zone()); |
| 417 ZoneVector<MachineType> tagged_type(1, kMachAnyTagged, zone()); | 420 ZoneVector<MachineType> tagged_type(1, MachineType::AnyTagged(), zone()); |
| 418 | 421 |
| 419 Callable callable = CodeFactory::ToObject(isolate()); | 422 Callable callable = CodeFactory::ToObject(isolate()); |
| 420 CallDescriptor* descriptor = Linkage::GetStubCallDescriptor( | 423 CallDescriptor* descriptor = Linkage::GetStubCallDescriptor( |
| 421 isolate(), zone(), callable.descriptor(), 1, | 424 isolate(), zone(), callable.descriptor(), 1, |
| 422 CallDescriptor::kNeedsFrameState, Operator::kNoProperties); | 425 CallDescriptor::kNeedsFrameState, Operator::kNoProperties); |
| 423 | 426 |
| 424 // Build frame state for the state before the call. | 427 // Build frame state for the state before the call. |
| 425 Node* parameters = | 428 Node* parameters = |
| 426 m.AddNode(m.common()->TypedStateValues(&int32_type), m.Int32Constant(43)); | 429 m.AddNode(m.common()->TypedStateValues(&int32_type), m.Int32Constant(43)); |
| 427 Node* locals = m.AddNode(m.common()->TypedStateValues(&float64_type), | 430 Node* locals = m.AddNode(m.common()->TypedStateValues(&float64_type), |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 EXPECT_EQ(OutputFrameStateCombine::kPushOutput, | 476 EXPECT_EQ(OutputFrameStateCombine::kPushOutput, |
| 474 desc_before->state_combine().kind()); | 477 desc_before->state_combine().kind()); |
| 475 EXPECT_EQ(1u, desc_before->parameters_count()); | 478 EXPECT_EQ(1u, desc_before->parameters_count()); |
| 476 EXPECT_EQ(1u, desc_before->locals_count()); | 479 EXPECT_EQ(1u, desc_before->locals_count()); |
| 477 EXPECT_EQ(1u, desc_before->stack_count()); | 480 EXPECT_EQ(1u, desc_before->stack_count()); |
| 478 EXPECT_EQ(43, s.ToInt32(call_instr->InputAt(3))); | 481 EXPECT_EQ(43, s.ToInt32(call_instr->InputAt(3))); |
| 479 EXPECT_EQ(0, s.ToInt32(call_instr->InputAt(4))); // This should be a context. | 482 EXPECT_EQ(0, s.ToInt32(call_instr->InputAt(4))); // This should be a context. |
| 480 // We inserted 0 here. | 483 // We inserted 0 here. |
| 481 EXPECT_EQ(0.5, s.ToFloat64(call_instr->InputAt(5))); | 484 EXPECT_EQ(0.5, s.ToFloat64(call_instr->InputAt(5))); |
| 482 EXPECT_TRUE(s.ToHeapObject(call_instr->InputAt(6))->IsUndefined()); | 485 EXPECT_TRUE(s.ToHeapObject(call_instr->InputAt(6))->IsUndefined()); |
| 483 EXPECT_EQ(kMachAnyTagged, desc_before->GetType(0)); // function is always | 486 EXPECT_EQ(MachineType::AnyTagged(), |
| 484 // tagged/any. | 487 desc_before->GetType(0)); // function is always |
| 485 EXPECT_EQ(kMachInt32, desc_before->GetType(1)); | 488 // tagged/any. |
| 486 EXPECT_EQ(kMachAnyTagged, desc_before->GetType(2)); // context is always | 489 EXPECT_EQ(MachineType::Int32(), desc_before->GetType(1)); |
| 487 // tagged/any. | 490 EXPECT_EQ(MachineType::AnyTagged(), |
| 488 EXPECT_EQ(kMachFloat64, desc_before->GetType(3)); | 491 desc_before->GetType(2)); // context is always |
| 489 EXPECT_EQ(kMachAnyTagged, desc_before->GetType(4)); | 492 // tagged/any. |
| 493 EXPECT_EQ(MachineType::Float64(), desc_before->GetType(3)); |
| 494 EXPECT_EQ(MachineType::AnyTagged(), desc_before->GetType(4)); |
| 490 | 495 |
| 491 // Function. | 496 // Function. |
| 492 EXPECT_EQ(s.ToVreg(function_node), s.ToVreg(call_instr->InputAt(7))); | 497 EXPECT_EQ(s.ToVreg(function_node), s.ToVreg(call_instr->InputAt(7))); |
| 493 // Context. | 498 // Context. |
| 494 EXPECT_EQ(s.ToVreg(context), s.ToVreg(call_instr->InputAt(8))); | 499 EXPECT_EQ(s.ToVreg(context), s.ToVreg(call_instr->InputAt(8))); |
| 495 | 500 |
| 496 EXPECT_EQ(kArchRet, s[index++]->arch_opcode()); | 501 EXPECT_EQ(kArchRet, s[index++]->arch_opcode()); |
| 497 | 502 |
| 498 EXPECT_EQ(index, s.size()); | 503 EXPECT_EQ(index, s.size()); |
| 499 } | 504 } |
| 500 | 505 |
| 501 | 506 |
| 502 TARGET_TEST_F(InstructionSelectorTest, CallStubWithDeoptRecursiveFrameState) { | 507 TARGET_TEST_F(InstructionSelectorTest, CallStubWithDeoptRecursiveFrameState) { |
| 503 StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged, kMachAnyTagged, | 508 StreamBuilder m(this, MachineType::AnyTagged(), MachineType::AnyTagged(), |
| 504 kMachAnyTagged); | 509 MachineType::AnyTagged(), MachineType::AnyTagged()); |
| 505 | 510 |
| 506 BailoutId bailout_id_before(42); | 511 BailoutId bailout_id_before(42); |
| 507 BailoutId bailout_id_parent(62); | 512 BailoutId bailout_id_parent(62); |
| 508 | 513 |
| 509 // Some arguments for the call node. | 514 // Some arguments for the call node. |
| 510 Node* function_node = m.Parameter(0); | 515 Node* function_node = m.Parameter(0); |
| 511 Node* receiver = m.Parameter(1); | 516 Node* receiver = m.Parameter(1); |
| 512 Node* context = m.Int32Constant(66); | 517 Node* context = m.Int32Constant(66); |
| 513 Node* context2 = m.Int32Constant(46); | 518 Node* context2 = m.Int32Constant(46); |
| 514 | 519 |
| 515 ZoneVector<MachineType> int32_type(1, kMachInt32, zone()); | 520 ZoneVector<MachineType> int32_type(1, MachineType::Int32(), zone()); |
| 516 ZoneVector<MachineType> int32x2_type(2, kMachInt32, zone()); | 521 ZoneVector<MachineType> int32x2_type(2, MachineType::Int32(), zone()); |
| 517 ZoneVector<MachineType> float64_type(1, kMachFloat64, zone()); | 522 ZoneVector<MachineType> float64_type(1, MachineType::Float64(), zone()); |
| 518 | 523 |
| 519 Callable callable = CodeFactory::ToObject(isolate()); | 524 Callable callable = CodeFactory::ToObject(isolate()); |
| 520 CallDescriptor* descriptor = Linkage::GetStubCallDescriptor( | 525 CallDescriptor* descriptor = Linkage::GetStubCallDescriptor( |
| 521 isolate(), zone(), callable.descriptor(), 1, | 526 isolate(), zone(), callable.descriptor(), 1, |
| 522 CallDescriptor::kNeedsFrameState, Operator::kNoProperties); | 527 CallDescriptor::kNeedsFrameState, Operator::kNoProperties); |
| 523 | 528 |
| 524 // Build frame state for the state before the call. | 529 // Build frame state for the state before the call. |
| 525 Node* parameters = | 530 Node* parameters = |
| 526 m.AddNode(m.common()->TypedStateValues(&int32_type), m.Int32Constant(63)); | 531 m.AddNode(m.common()->TypedStateValues(&int32_type), m.Int32Constant(63)); |
| 527 Node* locals = | 532 Node* locals = |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 579 // Deoptimization id. | 584 // Deoptimization id. |
| 580 int32_t deopt_id_before = s.ToInt32(call_instr->InputAt(1)); | 585 int32_t deopt_id_before = s.ToInt32(call_instr->InputAt(1)); |
| 581 FrameStateDescriptor* desc_before = | 586 FrameStateDescriptor* desc_before = |
| 582 s.GetFrameStateDescriptor(deopt_id_before); | 587 s.GetFrameStateDescriptor(deopt_id_before); |
| 583 FrameStateDescriptor* desc_before_outer = desc_before->outer_state(); | 588 FrameStateDescriptor* desc_before_outer = desc_before->outer_state(); |
| 584 EXPECT_EQ(bailout_id_before, desc_before->bailout_id()); | 589 EXPECT_EQ(bailout_id_before, desc_before->bailout_id()); |
| 585 EXPECT_EQ(1u, desc_before_outer->parameters_count()); | 590 EXPECT_EQ(1u, desc_before_outer->parameters_count()); |
| 586 EXPECT_EQ(1u, desc_before_outer->locals_count()); | 591 EXPECT_EQ(1u, desc_before_outer->locals_count()); |
| 587 EXPECT_EQ(1u, desc_before_outer->stack_count()); | 592 EXPECT_EQ(1u, desc_before_outer->stack_count()); |
| 588 // Values from parent environment. | 593 // Values from parent environment. |
| 589 EXPECT_EQ(kMachAnyTagged, desc_before->GetType(0)); | 594 EXPECT_EQ(MachineType::AnyTagged(), desc_before->GetType(0)); |
| 590 EXPECT_EQ(63, s.ToInt32(call_instr->InputAt(3))); | 595 EXPECT_EQ(63, s.ToInt32(call_instr->InputAt(3))); |
| 591 EXPECT_EQ(kMachInt32, desc_before_outer->GetType(1)); | 596 EXPECT_EQ(MachineType::Int32(), desc_before_outer->GetType(1)); |
| 592 // Context: | 597 // Context: |
| 593 EXPECT_EQ(66, s.ToInt32(call_instr->InputAt(4))); | 598 EXPECT_EQ(66, s.ToInt32(call_instr->InputAt(4))); |
| 594 EXPECT_EQ(kMachAnyTagged, desc_before_outer->GetType(2)); | 599 EXPECT_EQ(MachineType::AnyTagged(), desc_before_outer->GetType(2)); |
| 595 EXPECT_EQ(64, s.ToInt32(call_instr->InputAt(5))); | 600 EXPECT_EQ(64, s.ToInt32(call_instr->InputAt(5))); |
| 596 EXPECT_EQ(kMachInt32, desc_before_outer->GetType(3)); | 601 EXPECT_EQ(MachineType::Int32(), desc_before_outer->GetType(3)); |
| 597 EXPECT_EQ(65, s.ToInt32(call_instr->InputAt(6))); | 602 EXPECT_EQ(65, s.ToInt32(call_instr->InputAt(6))); |
| 598 EXPECT_EQ(kMachInt32, desc_before_outer->GetType(4)); | 603 EXPECT_EQ(MachineType::Int32(), desc_before_outer->GetType(4)); |
| 599 // Values from the nested frame. | 604 // Values from the nested frame. |
| 600 EXPECT_EQ(1u, desc_before->parameters_count()); | 605 EXPECT_EQ(1u, desc_before->parameters_count()); |
| 601 EXPECT_EQ(1u, desc_before->locals_count()); | 606 EXPECT_EQ(1u, desc_before->locals_count()); |
| 602 EXPECT_EQ(2u, desc_before->stack_count()); | 607 EXPECT_EQ(2u, desc_before->stack_count()); |
| 603 EXPECT_EQ(kMachAnyTagged, desc_before->GetType(0)); | 608 EXPECT_EQ(MachineType::AnyTagged(), desc_before->GetType(0)); |
| 604 EXPECT_EQ(43, s.ToInt32(call_instr->InputAt(8))); | 609 EXPECT_EQ(43, s.ToInt32(call_instr->InputAt(8))); |
| 605 EXPECT_EQ(kMachInt32, desc_before->GetType(1)); | 610 EXPECT_EQ(MachineType::Int32(), desc_before->GetType(1)); |
| 606 EXPECT_EQ(46, s.ToInt32(call_instr->InputAt(9))); | 611 EXPECT_EQ(46, s.ToInt32(call_instr->InputAt(9))); |
| 607 EXPECT_EQ(kMachAnyTagged, desc_before->GetType(2)); | 612 EXPECT_EQ(MachineType::AnyTagged(), desc_before->GetType(2)); |
| 608 EXPECT_EQ(0.25, s.ToFloat64(call_instr->InputAt(10))); | 613 EXPECT_EQ(0.25, s.ToFloat64(call_instr->InputAt(10))); |
| 609 EXPECT_EQ(kMachFloat64, desc_before->GetType(3)); | 614 EXPECT_EQ(MachineType::Float64(), desc_before->GetType(3)); |
| 610 EXPECT_EQ(44, s.ToInt32(call_instr->InputAt(11))); | 615 EXPECT_EQ(44, s.ToInt32(call_instr->InputAt(11))); |
| 611 EXPECT_EQ(kMachInt32, desc_before->GetType(4)); | 616 EXPECT_EQ(MachineType::Int32(), desc_before->GetType(4)); |
| 612 EXPECT_EQ(45, s.ToInt32(call_instr->InputAt(12))); | 617 EXPECT_EQ(45, s.ToInt32(call_instr->InputAt(12))); |
| 613 EXPECT_EQ(kMachInt32, desc_before->GetType(5)); | 618 EXPECT_EQ(MachineType::Int32(), desc_before->GetType(5)); |
| 614 | 619 |
| 615 // Function. | 620 // Function. |
| 616 EXPECT_EQ(s.ToVreg(function_node), s.ToVreg(call_instr->InputAt(13))); | 621 EXPECT_EQ(s.ToVreg(function_node), s.ToVreg(call_instr->InputAt(13))); |
| 617 // Context. | 622 // Context. |
| 618 EXPECT_EQ(s.ToVreg(context2), s.ToVreg(call_instr->InputAt(14))); | 623 EXPECT_EQ(s.ToVreg(context2), s.ToVreg(call_instr->InputAt(14))); |
| 619 // Continuation. | 624 // Continuation. |
| 620 | 625 |
| 621 EXPECT_EQ(kArchRet, s[index++]->arch_opcode()); | 626 EXPECT_EQ(kArchRet, s[index++]->arch_opcode()); |
| 622 EXPECT_EQ(index, s.size()); | 627 EXPECT_EQ(index, s.size()); |
| 623 } | 628 } |
| 624 | 629 |
| 625 } // namespace compiler | 630 } // namespace compiler |
| 626 } // namespace internal | 631 } // namespace internal |
| 627 } // namespace v8 | 632 } // namespace v8 |
| OLD | NEW |