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 |