| 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 3106 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4202     auto callable = tester.GetCallable<>(); | 4309     auto callable = tester.GetCallable<>(); | 
| 4203 | 4310 | 
| 4204     Handle<i::Object> return_value = callable().ToHandleChecked(); | 4311     Handle<i::Object> return_value = callable().ToHandleChecked(); | 
| 4205     CHECK(return_value->SameValue(*tests[i].second)); | 4312     CHECK(return_value->SameValue(*tests[i].second)); | 
| 4206   } | 4313   } | 
| 4207 } | 4314 } | 
| 4208 | 4315 | 
| 4209 }  // namespace interpreter | 4316 }  // namespace interpreter | 
| 4210 }  // namespace internal | 4317 }  // namespace internal | 
| 4211 }  // namespace v8 | 4318 }  // namespace v8 | 
| OLD | NEW | 
|---|