| 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/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/execution.h" | 7 #include "src/execution.h" |
| 8 #include "src/handles.h" | 8 #include "src/handles.h" |
| 9 #include "src/interpreter/bytecode-array-builder.h" | 9 #include "src/interpreter/bytecode-array-builder.h" |
| 10 #include "src/interpreter/bytecode-array-iterator.h" | 10 #include "src/interpreter/bytecode-array-iterator.h" |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 } | 260 } |
| 261 | 261 |
| 262 | 262 |
| 263 TEST(InterpreterShiftOpsSmi) { | 263 TEST(InterpreterShiftOpsSmi) { |
| 264 int lhs_inputs[] = {0, -17, -182, 1073741823, -1}; | 264 int lhs_inputs[] = {0, -17, -182, 1073741823, -1}; |
| 265 int rhs_inputs[] = {5, 2, 1, -1, -2, 0, 31, 32, -32, 64, 37}; | 265 int rhs_inputs[] = {5, 2, 1, -1, -2, 0, 31, 32, -32, 64, 37}; |
| 266 for (size_t l = 0; l < arraysize(lhs_inputs); l++) { | 266 for (size_t l = 0; l < arraysize(lhs_inputs); l++) { |
| 267 for (size_t r = 0; r < arraysize(rhs_inputs); r++) { | 267 for (size_t r = 0; r < arraysize(rhs_inputs); r++) { |
| 268 for (size_t o = 0; o < arraysize(kShiftOperators); o++) { | 268 for (size_t o = 0; o < arraysize(kShiftOperators); o++) { |
| 269 HandleAndZoneScope handles; | 269 HandleAndZoneScope handles; |
| 270 i::Factory* factory = handles.main_isolate()->factory(); | 270 i::Isolate* isolate = handles.main_isolate(); |
| 271 i::Factory* factory = isolate->factory(); |
| 272 i::Zone zone(isolate->allocator()); |
| 271 BytecodeArrayBuilder builder(handles.main_isolate(), | 273 BytecodeArrayBuilder builder(handles.main_isolate(), |
| 272 handles.main_zone(), 1, 0, 1); | 274 handles.main_zone(), 1, 0, 1); |
| 275 |
| 276 i::FeedbackVectorSpec feedback_spec(&zone); |
| 277 i::FeedbackVectorSlot slot = feedback_spec.AddGeneralSlot(); |
| 278 Handle<i::TypeFeedbackVector> vector = |
| 279 i::NewTypeFeedbackVector(isolate, &feedback_spec); |
| 280 |
| 273 Register reg(0); | 281 Register reg(0); |
| 274 int lhs = lhs_inputs[l]; | 282 int lhs = lhs_inputs[l]; |
| 275 int rhs = rhs_inputs[r]; | 283 int rhs = rhs_inputs[r]; |
| 276 builder.LoadLiteral(Smi::FromInt(lhs)) | 284 builder.LoadLiteral(Smi::FromInt(lhs)) |
| 277 .StoreAccumulatorInRegister(reg) | 285 .StoreAccumulatorInRegister(reg) |
| 278 .LoadLiteral(Smi::FromInt(rhs)) | 286 .LoadLiteral(Smi::FromInt(rhs)) |
| 279 .BinaryOperation(kShiftOperators[o], reg) | 287 .BinaryOperation(kShiftOperators[o], reg, vector->GetIndex(slot)) |
| 280 .Return(); | 288 .Return(); |
| 281 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 289 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 282 | 290 |
| 283 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 291 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 284 auto callable = tester.GetCallable<>(); | 292 auto callable = tester.GetCallable<>(); |
| 285 Handle<Object> return_value = callable().ToHandleChecked(); | 293 Handle<Object> return_value = callable().ToHandleChecked(); |
| 286 Handle<Object> expected_value = | 294 Handle<Object> expected_value = |
| 287 factory->NewNumber(BinaryOpC(kShiftOperators[o], lhs, rhs)); | 295 factory->NewNumber(BinaryOpC(kShiftOperators[o], lhs, rhs)); |
| 288 CHECK(return_value->SameValue(*expected_value)); | 296 CHECK(return_value->SameValue(*expected_value)); |
| 289 } | 297 } |
| 290 } | 298 } |
| 291 } | 299 } |
| 292 } | 300 } |
| 293 | 301 |
| 294 | 302 |
| 295 TEST(InterpreterBinaryOpsSmi) { | 303 TEST(InterpreterBinaryOpsSmi) { |
| 296 int lhs_inputs[] = {3266, 1024, 0, -17, -18000}; | 304 int lhs_inputs[] = {3266, 1024, 0, -17, -18000}; |
| 297 int rhs_inputs[] = {3266, 5, 4, 3, 2, 1, -1, -2}; | 305 int rhs_inputs[] = {3266, 5, 4, 3, 2, 1, -1, -2}; |
| 298 for (size_t l = 0; l < arraysize(lhs_inputs); l++) { | 306 for (size_t l = 0; l < arraysize(lhs_inputs); l++) { |
| 299 for (size_t r = 0; r < arraysize(rhs_inputs); r++) { | 307 for (size_t r = 0; r < arraysize(rhs_inputs); r++) { |
| 300 for (size_t o = 0; o < arraysize(kArithmeticOperators); o++) { | 308 for (size_t o = 0; o < arraysize(kArithmeticOperators); o++) { |
| 301 HandleAndZoneScope handles; | 309 HandleAndZoneScope handles; |
| 302 i::Factory* factory = handles.main_isolate()->factory(); | 310 i::Isolate* isolate = handles.main_isolate(); |
| 311 i::Factory* factory = isolate->factory(); |
| 312 i::Zone zone(isolate->allocator()); |
| 303 BytecodeArrayBuilder builder(handles.main_isolate(), | 313 BytecodeArrayBuilder builder(handles.main_isolate(), |
| 304 handles.main_zone(), 1, 0, 1); | 314 handles.main_zone(), 1, 0, 1); |
| 305 | 315 |
| 316 i::FeedbackVectorSpec feedback_spec(&zone); |
| 317 i::FeedbackVectorSlot slot = feedback_spec.AddGeneralSlot(); |
| 318 Handle<i::TypeFeedbackVector> vector = |
| 319 i::NewTypeFeedbackVector(isolate, &feedback_spec); |
| 320 |
| 306 Register reg(0); | 321 Register reg(0); |
| 307 int lhs = lhs_inputs[l]; | 322 int lhs = lhs_inputs[l]; |
| 308 int rhs = rhs_inputs[r]; | 323 int rhs = rhs_inputs[r]; |
| 309 builder.LoadLiteral(Smi::FromInt(lhs)) | 324 builder.LoadLiteral(Smi::FromInt(lhs)) |
| 310 .StoreAccumulatorInRegister(reg) | 325 .StoreAccumulatorInRegister(reg) |
| 311 .LoadLiteral(Smi::FromInt(rhs)) | 326 .LoadLiteral(Smi::FromInt(rhs)) |
| 312 .BinaryOperation(kArithmeticOperators[o], reg) | 327 .BinaryOperation(kArithmeticOperators[o], reg, |
| 328 vector->GetIndex(slot)) |
| 313 .Return(); | 329 .Return(); |
| 314 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 330 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 315 | 331 |
| 316 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 332 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 317 auto callable = tester.GetCallable<>(); | 333 auto callable = tester.GetCallable<>(); |
| 318 Handle<Object> return_value = callable().ToHandleChecked(); | 334 Handle<Object> return_value = callable().ToHandleChecked(); |
| 319 Handle<Object> expected_value = | 335 Handle<Object> expected_value = |
| 320 factory->NewNumber(BinaryOpC(kArithmeticOperators[o], lhs, rhs)); | 336 factory->NewNumber(BinaryOpC(kArithmeticOperators[o], lhs, rhs)); |
| 321 CHECK(return_value->SameValue(*expected_value)); | 337 CHECK(return_value->SameValue(*expected_value)); |
| 322 } | 338 } |
| 323 } | 339 } |
| 324 } | 340 } |
| 325 } | 341 } |
| 326 | 342 |
| 327 | 343 |
| 328 TEST(InterpreterBinaryOpsHeapNumber) { | 344 TEST(InterpreterBinaryOpsHeapNumber) { |
| 329 double lhs_inputs[] = {3266.101, 1024.12, 0.01, -17.99, -18000.833, 9.1e17}; | 345 double lhs_inputs[] = {3266.101, 1024.12, 0.01, -17.99, -18000.833, 9.1e17}; |
| 330 double rhs_inputs[] = {3266.101, 5.999, 4.778, 3.331, 2.643, | 346 double rhs_inputs[] = {3266.101, 5.999, 4.778, 3.331, 2.643, |
| 331 1.1, -1.8, -2.9, 8.3e-27}; | 347 1.1, -1.8, -2.9, 8.3e-27}; |
| 332 for (size_t l = 0; l < arraysize(lhs_inputs); l++) { | 348 for (size_t l = 0; l < arraysize(lhs_inputs); l++) { |
| 333 for (size_t r = 0; r < arraysize(rhs_inputs); r++) { | 349 for (size_t r = 0; r < arraysize(rhs_inputs); r++) { |
| 334 for (size_t o = 0; o < arraysize(kArithmeticOperators); o++) { | 350 for (size_t o = 0; o < arraysize(kArithmeticOperators); o++) { |
| 335 HandleAndZoneScope handles; | 351 HandleAndZoneScope handles; |
| 336 i::Factory* factory = handles.main_isolate()->factory(); | 352 i::Isolate* isolate = handles.main_isolate(); |
| 353 i::Factory* factory = isolate->factory(); |
| 354 i::Zone zone(isolate->allocator()); |
| 337 BytecodeArrayBuilder builder(handles.main_isolate(), | 355 BytecodeArrayBuilder builder(handles.main_isolate(), |
| 338 handles.main_zone(), 1, 0, 1); | 356 handles.main_zone(), 1, 0, 1); |
| 357 |
| 358 i::FeedbackVectorSpec feedback_spec(&zone); |
| 359 i::FeedbackVectorSlot slot = feedback_spec.AddGeneralSlot(); |
| 360 Handle<i::TypeFeedbackVector> vector = |
| 361 i::NewTypeFeedbackVector(isolate, &feedback_spec); |
| 362 |
| 339 Register reg(0); | 363 Register reg(0); |
| 340 double lhs = lhs_inputs[l]; | 364 double lhs = lhs_inputs[l]; |
| 341 double rhs = rhs_inputs[r]; | 365 double rhs = rhs_inputs[r]; |
| 342 builder.LoadLiteral(factory->NewNumber(lhs)) | 366 builder.LoadLiteral(factory->NewNumber(lhs)) |
| 343 .StoreAccumulatorInRegister(reg) | 367 .StoreAccumulatorInRegister(reg) |
| 344 .LoadLiteral(factory->NewNumber(rhs)) | 368 .LoadLiteral(factory->NewNumber(rhs)) |
| 345 .BinaryOperation(kArithmeticOperators[o], reg) | 369 .BinaryOperation(kArithmeticOperators[o], reg, |
| 370 vector->GetIndex(slot)) |
| 346 .Return(); | 371 .Return(); |
| 347 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 372 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 348 | 373 |
| 349 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 374 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 350 auto callable = tester.GetCallable<>(); | 375 auto callable = tester.GetCallable<>(); |
| 351 Handle<Object> return_value = callable().ToHandleChecked(); | 376 Handle<Object> return_value = callable().ToHandleChecked(); |
| 352 Handle<Object> expected_value = | 377 Handle<Object> expected_value = |
| 353 factory->NewNumber(BinaryOpC(kArithmeticOperators[o], lhs, rhs)); | 378 factory->NewNumber(BinaryOpC(kArithmeticOperators[o], lhs, rhs)); |
| 354 CHECK(return_value->SameValue(*expected_value)); | 379 CHECK(return_value->SameValue(*expected_value)); |
| 355 } | 380 } |
| 356 } | 381 } |
| 357 } | 382 } |
| 358 } | 383 } |
| 359 | 384 |
| 360 | 385 |
| 361 TEST(InterpreterStringAdd) { | 386 TEST(InterpreterStringAdd) { |
| 362 HandleAndZoneScope handles; | 387 HandleAndZoneScope handles; |
| 363 i::Factory* factory = handles.main_isolate()->factory(); | 388 i::Isolate* isolate = handles.main_isolate(); |
| 389 i::Factory* factory = isolate->factory(); |
| 390 i::Zone zone(isolate->allocator()); |
| 364 | 391 |
| 365 struct TestCase { | 392 struct TestCase { |
| 366 Handle<Object> lhs; | 393 Handle<Object> lhs; |
| 367 Handle<Object> rhs; | 394 Handle<Object> rhs; |
| 368 Handle<Object> expected_value; | 395 Handle<Object> expected_value; |
| 369 } test_cases[] = { | 396 } test_cases[] = { |
| 370 {factory->NewStringFromStaticChars("a"), | 397 {factory->NewStringFromStaticChars("a"), |
| 371 factory->NewStringFromStaticChars("b"), | 398 factory->NewStringFromStaticChars("b"), |
| 372 factory->NewStringFromStaticChars("ab")}, | 399 factory->NewStringFromStaticChars("ab")}, |
| 373 {factory->NewStringFromStaticChars("aaaaaa"), | 400 {factory->NewStringFromStaticChars("aaaaaa"), |
| (...skipping 12 matching lines...) Expand all Loading... |
| 386 factory->NewStringFromStaticChars("1.112.5")}, | 413 factory->NewStringFromStaticChars("1.112.5")}, |
| 387 {factory->NewStringFromStaticChars("-1.11"), factory->NewHeapNumber(2.56), | 414 {factory->NewStringFromStaticChars("-1.11"), factory->NewHeapNumber(2.56), |
| 388 factory->NewStringFromStaticChars("-1.112.56")}, | 415 factory->NewStringFromStaticChars("-1.112.56")}, |
| 389 {factory->NewStringFromStaticChars(""), factory->NewHeapNumber(2.5), | 416 {factory->NewStringFromStaticChars(""), factory->NewHeapNumber(2.5), |
| 390 factory->NewStringFromStaticChars("2.5")}, | 417 factory->NewStringFromStaticChars("2.5")}, |
| 391 }; | 418 }; |
| 392 | 419 |
| 393 for (size_t i = 0; i < arraysize(test_cases); i++) { | 420 for (size_t i = 0; i < arraysize(test_cases); i++) { |
| 394 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 1, | 421 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 1, |
| 395 0, 1); | 422 0, 1); |
| 423 i::FeedbackVectorSpec feedback_spec(&zone); |
| 424 i::FeedbackVectorSlot slot = feedback_spec.AddGeneralSlot(); |
| 425 Handle<i::TypeFeedbackVector> vector = |
| 426 i::NewTypeFeedbackVector(isolate, &feedback_spec); |
| 396 | 427 |
| 397 Register reg(0); | 428 Register reg(0); |
| 398 builder.LoadLiteral(test_cases[i].lhs) | 429 builder.LoadLiteral(test_cases[i].lhs) |
| 399 .StoreAccumulatorInRegister(reg) | 430 .StoreAccumulatorInRegister(reg) |
| 400 .LoadLiteral(test_cases[i].rhs) | 431 .LoadLiteral(test_cases[i].rhs) |
| 401 .BinaryOperation(Token::Value::ADD, reg) | 432 .BinaryOperation(Token::Value::ADD, reg, vector->GetIndex(slot)) |
| 402 .Return(); | 433 .Return(); |
| 403 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 434 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 404 | 435 |
| 405 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 436 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 406 auto callable = tester.GetCallable<>(); | 437 auto callable = tester.GetCallable<>(); |
| 407 Handle<Object> return_value = callable().ToHandleChecked(); | 438 Handle<Object> return_value = callable().ToHandleChecked(); |
| 408 CHECK(return_value->SameValue(*test_cases[i].expected_value)); | 439 CHECK(return_value->SameValue(*test_cases[i].expected_value)); |
| 409 } | 440 } |
| 410 } | 441 } |
| 411 | 442 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 428 | 459 |
| 429 // Check for Smis. | 460 // Check for Smis. |
| 430 return_val = callable(Handle<Smi>(Smi::FromInt(3), handles.main_isolate())) | 461 return_val = callable(Handle<Smi>(Smi::FromInt(3), handles.main_isolate())) |
| 431 .ToHandleChecked(); | 462 .ToHandleChecked(); |
| 432 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(3)); | 463 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(3)); |
| 433 } | 464 } |
| 434 | 465 |
| 435 | 466 |
| 436 TEST(InterpreterParameter8) { | 467 TEST(InterpreterParameter8) { |
| 437 HandleAndZoneScope handles; | 468 HandleAndZoneScope handles; |
| 469 i::Isolate* isolate = handles.main_isolate(); |
| 470 i::Zone zone(isolate->allocator()); |
| 438 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 8, | 471 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 8, |
| 439 0, 0); | 472 0, 0); |
| 440 | 473 |
| 474 i::FeedbackVectorSpec feedback_spec(&zone); |
| 475 i::FeedbackVectorSlot slot = feedback_spec.AddGeneralSlot(); |
| 476 i::FeedbackVectorSlot slot1 = feedback_spec.AddGeneralSlot(); |
| 477 i::FeedbackVectorSlot slot2 = feedback_spec.AddGeneralSlot(); |
| 478 i::FeedbackVectorSlot slot3 = feedback_spec.AddGeneralSlot(); |
| 479 i::FeedbackVectorSlot slot4 = feedback_spec.AddGeneralSlot(); |
| 480 i::FeedbackVectorSlot slot5 = feedback_spec.AddGeneralSlot(); |
| 481 i::FeedbackVectorSlot slot6 = feedback_spec.AddGeneralSlot(); |
| 482 |
| 483 Handle<i::TypeFeedbackVector> vector = |
| 484 i::NewTypeFeedbackVector(isolate, &feedback_spec); |
| 485 |
| 441 builder.LoadAccumulatorWithRegister(builder.Parameter(0)) | 486 builder.LoadAccumulatorWithRegister(builder.Parameter(0)) |
| 442 .BinaryOperation(Token::Value::ADD, builder.Parameter(1)) | 487 .BinaryOperation(Token::Value::ADD, builder.Parameter(1), |
| 443 .BinaryOperation(Token::Value::ADD, builder.Parameter(2)) | 488 vector->GetIndex(slot)) |
| 444 .BinaryOperation(Token::Value::ADD, builder.Parameter(3)) | 489 .BinaryOperation(Token::Value::ADD, builder.Parameter(2), |
| 445 .BinaryOperation(Token::Value::ADD, builder.Parameter(4)) | 490 vector->GetIndex(slot1)) |
| 446 .BinaryOperation(Token::Value::ADD, builder.Parameter(5)) | 491 .BinaryOperation(Token::Value::ADD, builder.Parameter(3), |
| 447 .BinaryOperation(Token::Value::ADD, builder.Parameter(6)) | 492 vector->GetIndex(slot2)) |
| 448 .BinaryOperation(Token::Value::ADD, builder.Parameter(7)) | 493 .BinaryOperation(Token::Value::ADD, builder.Parameter(4), |
| 494 vector->GetIndex(slot3)) |
| 495 .BinaryOperation(Token::Value::ADD, builder.Parameter(5), |
| 496 vector->GetIndex(slot4)) |
| 497 .BinaryOperation(Token::Value::ADD, builder.Parameter(6), |
| 498 vector->GetIndex(slot5)) |
| 499 .BinaryOperation(Token::Value::ADD, builder.Parameter(7), |
| 500 vector->GetIndex(slot6)) |
| 449 .Return(); | 501 .Return(); |
| 450 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 502 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 451 | 503 |
| 452 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 504 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 453 typedef Handle<Object> H; | 505 typedef Handle<Object> H; |
| 454 auto callable = tester.GetCallable<H, H, H, H, H, H, H, H>(); | 506 auto callable = tester.GetCallable<H, H, H, H, H, H, H, H>(); |
| 455 | 507 |
| 456 Handle<Smi> arg1 = Handle<Smi>(Smi::FromInt(1), handles.main_isolate()); | 508 Handle<Smi> arg1 = Handle<Smi>(Smi::FromInt(1), handles.main_isolate()); |
| 457 Handle<Smi> arg2 = Handle<Smi>(Smi::FromInt(2), handles.main_isolate()); | 509 Handle<Smi> arg2 = Handle<Smi>(Smi::FromInt(2), handles.main_isolate()); |
| 458 Handle<Smi> arg3 = Handle<Smi>(Smi::FromInt(3), handles.main_isolate()); | 510 Handle<Smi> arg3 = Handle<Smi>(Smi::FromInt(3), handles.main_isolate()); |
| (...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 946 | 998 |
| 947 static BytecodeArrayBuilder& SetRegister(BytecodeArrayBuilder& builder, | 999 static BytecodeArrayBuilder& SetRegister(BytecodeArrayBuilder& builder, |
| 948 Register reg, int value, | 1000 Register reg, int value, |
| 949 Register scratch) { | 1001 Register scratch) { |
| 950 return builder.StoreAccumulatorInRegister(scratch) | 1002 return builder.StoreAccumulatorInRegister(scratch) |
| 951 .LoadLiteral(Smi::FromInt(value)) | 1003 .LoadLiteral(Smi::FromInt(value)) |
| 952 .StoreAccumulatorInRegister(reg) | 1004 .StoreAccumulatorInRegister(reg) |
| 953 .LoadAccumulatorWithRegister(scratch); | 1005 .LoadAccumulatorWithRegister(scratch); |
| 954 } | 1006 } |
| 955 | 1007 |
| 956 | |
| 957 static BytecodeArrayBuilder& IncrementRegister(BytecodeArrayBuilder& builder, | 1008 static BytecodeArrayBuilder& IncrementRegister(BytecodeArrayBuilder& builder, |
| 958 Register reg, int value, | 1009 Register reg, int value, |
| 959 Register scratch) { | 1010 Register scratch, |
| 1011 int slot_index) { |
| 960 return builder.StoreAccumulatorInRegister(scratch) | 1012 return builder.StoreAccumulatorInRegister(scratch) |
| 961 .LoadLiteral(Smi::FromInt(value)) | 1013 .LoadLiteral(Smi::FromInt(value)) |
| 962 .BinaryOperation(Token::Value::ADD, reg) | 1014 .BinaryOperation(Token::Value::ADD, reg, slot_index) |
| 963 .StoreAccumulatorInRegister(reg) | 1015 .StoreAccumulatorInRegister(reg) |
| 964 .LoadAccumulatorWithRegister(scratch); | 1016 .LoadAccumulatorWithRegister(scratch); |
| 965 } | 1017 } |
| 966 | 1018 |
| 967 | 1019 |
| 968 TEST(InterpreterJumps) { | 1020 TEST(InterpreterJumps) { |
| 969 HandleAndZoneScope handles; | 1021 HandleAndZoneScope handles; |
| 1022 i::Isolate* isolate = handles.main_isolate(); |
| 1023 i::Zone zone(isolate->allocator()); |
| 970 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 0, | 1024 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 0, |
| 971 0, 2); | 1025 0, 2); |
| 972 | 1026 |
| 1027 i::FeedbackVectorSpec feedback_spec(&zone); |
| 1028 i::FeedbackVectorSlot slot = feedback_spec.AddGeneralSlot(); |
| 1029 i::FeedbackVectorSlot slot1 = feedback_spec.AddGeneralSlot(); |
| 1030 i::FeedbackVectorSlot slot2 = feedback_spec.AddGeneralSlot(); |
| 1031 |
| 1032 Handle<i::TypeFeedbackVector> vector = |
| 1033 i::NewTypeFeedbackVector(isolate, &feedback_spec); |
| 1034 |
| 973 Register reg(0), scratch(1); | 1035 Register reg(0), scratch(1); |
| 974 BytecodeLabel label[3]; | 1036 BytecodeLabel label[3]; |
| 975 | 1037 |
| 976 builder.LoadLiteral(Smi::FromInt(0)) | 1038 builder.LoadLiteral(Smi::FromInt(0)) |
| 977 .StoreAccumulatorInRegister(reg) | 1039 .StoreAccumulatorInRegister(reg) |
| 978 .Jump(&label[1]); | 1040 .Jump(&label[1]); |
| 979 SetRegister(builder, reg, 1024, scratch).Bind(&label[0]); | 1041 SetRegister(builder, reg, 1024, scratch).Bind(&label[0]); |
| 980 IncrementRegister(builder, reg, 1, scratch).Jump(&label[2]); | 1042 IncrementRegister(builder, reg, 1, scratch, vector->GetIndex(slot)) |
| 1043 .Jump(&label[2]); |
| 981 SetRegister(builder, reg, 2048, scratch).Bind(&label[1]); | 1044 SetRegister(builder, reg, 2048, scratch).Bind(&label[1]); |
| 982 IncrementRegister(builder, reg, 2, scratch).Jump(&label[0]); | 1045 IncrementRegister(builder, reg, 2, scratch, vector->GetIndex(slot1)) |
| 1046 .Jump(&label[0]); |
| 983 SetRegister(builder, reg, 4096, scratch).Bind(&label[2]); | 1047 SetRegister(builder, reg, 4096, scratch).Bind(&label[2]); |
| 984 IncrementRegister(builder, reg, 4, scratch) | 1048 IncrementRegister(builder, reg, 4, scratch, vector->GetIndex(slot2)) |
| 985 .LoadAccumulatorWithRegister(reg) | 1049 .LoadAccumulatorWithRegister(reg) |
| 986 .Return(); | 1050 .Return(); |
| 987 | 1051 |
| 988 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 1052 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 989 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 1053 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 990 auto callable = tester.GetCallable<>(); | 1054 auto callable = tester.GetCallable<>(); |
| 991 Handle<Object> return_value = callable().ToHandleChecked(); | 1055 Handle<Object> return_value = callable().ToHandleChecked(); |
| 992 CHECK_EQ(Smi::cast(*return_value)->value(), 7); | 1056 CHECK_EQ(Smi::cast(*return_value)->value(), 7); |
| 993 } | 1057 } |
| 994 | 1058 |
| 995 | 1059 |
| 996 TEST(InterpreterConditionalJumps) { | 1060 TEST(InterpreterConditionalJumps) { |
| 997 HandleAndZoneScope handles; | 1061 HandleAndZoneScope handles; |
| 1062 i::Isolate* isolate = handles.main_isolate(); |
| 1063 i::Zone zone(isolate->allocator()); |
| 998 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 0, | 1064 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 0, |
| 999 0, 2); | 1065 0, 2); |
| 1000 | 1066 |
| 1067 i::FeedbackVectorSpec feedback_spec(&zone); |
| 1068 i::FeedbackVectorSlot slot = feedback_spec.AddGeneralSlot(); |
| 1069 i::FeedbackVectorSlot slot1 = feedback_spec.AddGeneralSlot(); |
| 1070 i::FeedbackVectorSlot slot2 = feedback_spec.AddGeneralSlot(); |
| 1071 i::FeedbackVectorSlot slot3 = feedback_spec.AddGeneralSlot(); |
| 1072 i::FeedbackVectorSlot slot4 = feedback_spec.AddGeneralSlot(); |
| 1073 |
| 1074 Handle<i::TypeFeedbackVector> vector = |
| 1075 i::NewTypeFeedbackVector(isolate, &feedback_spec); |
| 1076 |
| 1001 Register reg(0), scratch(1); | 1077 Register reg(0), scratch(1); |
| 1002 BytecodeLabel label[2]; | 1078 BytecodeLabel label[2]; |
| 1003 BytecodeLabel done, done1; | 1079 BytecodeLabel done, done1; |
| 1004 | 1080 |
| 1005 builder.LoadLiteral(Smi::FromInt(0)) | 1081 builder.LoadLiteral(Smi::FromInt(0)) |
| 1006 .StoreAccumulatorInRegister(reg) | 1082 .StoreAccumulatorInRegister(reg) |
| 1007 .LoadFalse() | 1083 .LoadFalse() |
| 1008 .JumpIfFalse(&label[0]); | 1084 .JumpIfFalse(&label[0]); |
| 1009 IncrementRegister(builder, reg, 1024, scratch) | 1085 IncrementRegister(builder, reg, 1024, scratch, vector->GetIndex(slot)) |
| 1010 .Bind(&label[0]) | 1086 .Bind(&label[0]) |
| 1011 .LoadTrue() | 1087 .LoadTrue() |
| 1012 .JumpIfFalse(&done); | 1088 .JumpIfFalse(&done); |
| 1013 IncrementRegister(builder, reg, 1, scratch).LoadTrue().JumpIfTrue(&label[1]); | 1089 IncrementRegister(builder, reg, 1, scratch, vector->GetIndex(slot1)) |
| 1014 IncrementRegister(builder, reg, 2048, scratch).Bind(&label[1]); | 1090 .LoadTrue() |
| 1015 IncrementRegister(builder, reg, 2, scratch).LoadFalse().JumpIfTrue(&done1); | 1091 .JumpIfTrue(&label[1]); |
| 1016 IncrementRegister(builder, reg, 4, scratch) | 1092 IncrementRegister(builder, reg, 2048, scratch, vector->GetIndex(slot2)) |
| 1093 .Bind(&label[1]); |
| 1094 IncrementRegister(builder, reg, 2, scratch, vector->GetIndex(slot3)) |
| 1095 .LoadFalse() |
| 1096 .JumpIfTrue(&done1); |
| 1097 IncrementRegister(builder, reg, 4, scratch, vector->GetIndex(slot4)) |
| 1017 .LoadAccumulatorWithRegister(reg) | 1098 .LoadAccumulatorWithRegister(reg) |
| 1018 .Bind(&done) | 1099 .Bind(&done) |
| 1019 .Bind(&done1) | 1100 .Bind(&done1) |
| 1020 .Return(); | 1101 .Return(); |
| 1021 | 1102 |
| 1022 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 1103 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 1023 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 1104 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 1024 auto callable = tester.GetCallable<>(); | 1105 auto callable = tester.GetCallable<>(); |
| 1025 Handle<Object> return_value = callable().ToHandleChecked(); | 1106 Handle<Object> return_value = callable().ToHandleChecked(); |
| 1026 CHECK_EQ(Smi::cast(*return_value)->value(), 7); | 1107 CHECK_EQ(Smi::cast(*return_value)->value(), 7); |
| 1027 } | 1108 } |
| 1028 | 1109 |
| 1029 TEST(InterpreterConditionalJumps2) { | 1110 TEST(InterpreterConditionalJumps2) { |
| 1030 // TODO(oth): Add tests for all conditional jumps near and far. | 1111 // TODO(oth): Add tests for all conditional jumps near and far. |
| 1031 HandleAndZoneScope handles; | 1112 HandleAndZoneScope handles; |
| 1113 i::Isolate* isolate = handles.main_isolate(); |
| 1114 i::Zone zone(isolate->allocator()); |
| 1032 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 0, | 1115 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 0, |
| 1033 0, 2); | 1116 0, 2); |
| 1034 | 1117 |
| 1118 i::FeedbackVectorSpec feedback_spec(&zone); |
| 1119 i::FeedbackVectorSlot slot = feedback_spec.AddGeneralSlot(); |
| 1120 i::FeedbackVectorSlot slot1 = feedback_spec.AddGeneralSlot(); |
| 1121 i::FeedbackVectorSlot slot2 = feedback_spec.AddGeneralSlot(); |
| 1122 i::FeedbackVectorSlot slot3 = feedback_spec.AddGeneralSlot(); |
| 1123 i::FeedbackVectorSlot slot4 = feedback_spec.AddGeneralSlot(); |
| 1124 |
| 1125 Handle<i::TypeFeedbackVector> vector = |
| 1126 i::NewTypeFeedbackVector(isolate, &feedback_spec); |
| 1127 |
| 1035 Register reg(0), scratch(1); | 1128 Register reg(0), scratch(1); |
| 1036 BytecodeLabel label[2]; | 1129 BytecodeLabel label[2]; |
| 1037 BytecodeLabel done, done1; | 1130 BytecodeLabel done, done1; |
| 1038 | 1131 |
| 1039 builder.LoadLiteral(Smi::FromInt(0)) | 1132 builder.LoadLiteral(Smi::FromInt(0)) |
| 1040 .StoreAccumulatorInRegister(reg) | 1133 .StoreAccumulatorInRegister(reg) |
| 1041 .LoadFalse() | 1134 .LoadFalse() |
| 1042 .JumpIfFalse(&label[0]); | 1135 .JumpIfFalse(&label[0]); |
| 1043 IncrementRegister(builder, reg, 1024, scratch) | 1136 IncrementRegister(builder, reg, 1024, scratch, vector->GetIndex(slot)) |
| 1044 .Bind(&label[0]) | 1137 .Bind(&label[0]) |
| 1045 .LoadTrue() | 1138 .LoadTrue() |
| 1046 .JumpIfFalse(&done); | 1139 .JumpIfFalse(&done); |
| 1047 IncrementRegister(builder, reg, 1, scratch).LoadTrue().JumpIfTrue(&label[1]); | 1140 IncrementRegister(builder, reg, 1, scratch, vector->GetIndex(slot1)) |
| 1048 IncrementRegister(builder, reg, 2048, scratch).Bind(&label[1]); | 1141 .LoadTrue() |
| 1049 IncrementRegister(builder, reg, 2, scratch).LoadFalse().JumpIfTrue(&done1); | 1142 .JumpIfTrue(&label[1]); |
| 1050 IncrementRegister(builder, reg, 4, scratch) | 1143 IncrementRegister(builder, reg, 2048, scratch, vector->GetIndex(slot2)) |
| 1144 .Bind(&label[1]); |
| 1145 IncrementRegister(builder, reg, 2, scratch, vector->GetIndex(slot3)) |
| 1146 .LoadFalse() |
| 1147 .JumpIfTrue(&done1); |
| 1148 IncrementRegister(builder, reg, 4, scratch, vector->GetIndex(slot4)) |
| 1051 .LoadAccumulatorWithRegister(reg) | 1149 .LoadAccumulatorWithRegister(reg) |
| 1052 .Bind(&done) | 1150 .Bind(&done) |
| 1053 .Bind(&done1) | 1151 .Bind(&done1) |
| 1054 .Return(); | 1152 .Return(); |
| 1055 | 1153 |
| 1056 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 1154 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 1057 InterpreterTester tester(handles.main_isolate(), bytecode_array); | 1155 InterpreterTester tester(handles.main_isolate(), bytecode_array); |
| 1058 auto callable = tester.GetCallable<>(); | 1156 auto callable = tester.GetCallable<>(); |
| 1059 Handle<Object> return_value = callable().ToHandleChecked(); | 1157 Handle<Object> return_value = callable().ToHandleChecked(); |
| 1060 CHECK_EQ(Smi::cast(*return_value)->value(), 7); | 1158 CHECK_EQ(Smi::cast(*return_value)->value(), 7); |
| 1061 } | 1159 } |
| 1062 | 1160 |
| 1063 TEST(InterpreterJumpConstantWith16BitOperand) { | 1161 TEST(InterpreterJumpConstantWith16BitOperand) { |
| 1064 HandleAndZoneScope handles; | 1162 HandleAndZoneScope handles; |
| 1065 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 1, | 1163 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 1, |
| 1066 0, 257); | 1164 0, 257); |
| 1067 | 1165 |
| 1166 i::Isolate* isolate = handles.main_isolate(); |
| 1167 i::Zone zone(isolate->allocator()); |
| 1168 |
| 1169 i::FeedbackVectorSpec feedback_spec(&zone); |
| 1170 i::FeedbackVectorSlot slot = feedback_spec.AddGeneralSlot(); |
| 1171 Handle<i::TypeFeedbackVector> vector = |
| 1172 i::NewTypeFeedbackVector(isolate, &feedback_spec); |
| 1173 |
| 1068 Register reg(0), scratch(256); | 1174 Register reg(0), scratch(256); |
| 1069 BytecodeLabel done, fake; | 1175 BytecodeLabel done, fake; |
| 1070 | 1176 |
| 1071 builder.LoadLiteral(Smi::FromInt(0)); | 1177 builder.LoadLiteral(Smi::FromInt(0)); |
| 1072 builder.StoreAccumulatorInRegister(reg); | 1178 builder.StoreAccumulatorInRegister(reg); |
| 1073 // Consume all 8-bit operands | 1179 // Consume all 8-bit operands |
| 1074 for (int i = 1; i <= 256; i++) { | 1180 for (int i = 1; i <= 256; i++) { |
| 1075 builder.LoadLiteral(handles.main_isolate()->factory()->NewNumber(i)); | 1181 builder.LoadLiteral(handles.main_isolate()->factory()->NewNumber(i)); |
| 1076 builder.BinaryOperation(Token::Value::ADD, reg); | 1182 builder.BinaryOperation(Token::Value::ADD, reg, vector->GetIndex(slot)); |
| 1077 builder.StoreAccumulatorInRegister(reg); | 1183 builder.StoreAccumulatorInRegister(reg); |
| 1078 } | 1184 } |
| 1079 builder.Jump(&done); | 1185 builder.Jump(&done); |
| 1080 | 1186 |
| 1081 // Emit more than 16-bit immediate operands worth of code to jump over. | 1187 // Emit more than 16-bit immediate operands worth of code to jump over. |
| 1082 builder.Bind(&fake); | 1188 builder.Bind(&fake); |
| 1083 for (int i = 0; i < 6600; i++) { | 1189 for (int i = 0; i < 6600; i++) { |
| 1084 builder.LoadLiteral(Smi::FromInt(0)); // 1-byte | 1190 builder.LoadLiteral(Smi::FromInt(0)); // 1-byte |
| 1085 builder.BinaryOperation(Token::Value::ADD, scratch); // 4-bytes | 1191 builder.BinaryOperation(Token::Value::ADD, scratch, |
| 1192 vector->GetIndex(slot)); // 6-bytes |
| 1086 builder.StoreAccumulatorInRegister(scratch); // 4-bytes | 1193 builder.StoreAccumulatorInRegister(scratch); // 4-bytes |
| 1087 builder.MoveRegister(scratch, reg); // 6-bytes | 1194 builder.MoveRegister(scratch, reg); // 6-bytes |
| 1088 } | 1195 } |
| 1089 builder.Bind(&done); | 1196 builder.Bind(&done); |
| 1090 builder.LoadAccumulatorWithRegister(reg); | 1197 builder.LoadAccumulatorWithRegister(reg); |
| 1091 builder.Return(); | 1198 builder.Return(); |
| 1092 | 1199 |
| 1093 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); | 1200 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); |
| 1094 BytecodeArrayIterator iterator(bytecode_array); | 1201 BytecodeArrayIterator iterator(bytecode_array); |
| 1095 | 1202 |
| (...skipping 3108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4204 auto callable = tester.GetCallable<>(); | 4311 auto callable = tester.GetCallable<>(); |
| 4205 | 4312 |
| 4206 Handle<i::Object> return_value = callable().ToHandleChecked(); | 4313 Handle<i::Object> return_value = callable().ToHandleChecked(); |
| 4207 CHECK(return_value->SameValue(*tests[i].second)); | 4314 CHECK(return_value->SameValue(*tests[i].second)); |
| 4208 } | 4315 } |
| 4209 } | 4316 } |
| 4210 | 4317 |
| 4211 } // namespace interpreter | 4318 } // namespace interpreter |
| 4212 } // namespace internal | 4319 } // namespace internal |
| 4213 } // namespace v8 | 4320 } // namespace v8 |
| OLD | NEW |