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 <tuple> | 5 #include <tuple> |
6 | 6 |
7 #include "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #include "src/execution.h" | 9 #include "src/execution.h" |
10 #include "src/handles.h" | 10 #include "src/handles.h" |
11 #include "src/interpreter/bytecode-array-builder.h" | 11 #include "src/interpreter/bytecode-array-builder.h" |
12 #include "src/interpreter/bytecode-array-iterator.h" | 12 #include "src/interpreter/bytecode-array-iterator.h" |
13 #include "src/interpreter/bytecode-label.h" | 13 #include "src/interpreter/bytecode-label.h" |
14 #include "src/interpreter/interpreter.h" | 14 #include "src/interpreter/interpreter.h" |
15 #include "src/objects-inl.h" | 15 #include "src/objects-inl.h" |
16 #include "src/unicode-cache.h" | 16 #include "src/unicode-cache.h" |
17 #include "test/cctest/cctest.h" | 17 #include "test/cctest/cctest.h" |
18 #include "test/cctest/interpreter/interpreter-tester.h" | 18 #include "test/cctest/interpreter/interpreter-tester.h" |
19 #include "test/cctest/test-feedback-vector.h" | 19 #include "test/cctest/test-feedback-vector.h" |
20 | 20 |
21 namespace v8 { | 21 namespace v8 { |
22 namespace internal { | 22 namespace internal { |
23 namespace interpreter { | 23 namespace interpreter { |
24 | 24 |
| 25 static int GetIndex(FeedbackVectorSlot slot) { |
| 26 return TypeFeedbackVector::GetIndex(slot); |
| 27 } |
25 | 28 |
26 TEST(InterpreterReturn) { | 29 TEST(InterpreterReturn) { |
27 HandleAndZoneScope handles; | 30 HandleAndZoneScope handles; |
28 Isolate* isolate = handles.main_isolate(); | 31 Isolate* isolate = handles.main_isolate(); |
29 Handle<Object> undefined_value = isolate->factory()->undefined_value(); | 32 Handle<Object> undefined_value = isolate->factory()->undefined_value(); |
30 | 33 |
31 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 0); | 34 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 0); |
32 builder.Return(); | 35 builder.Return(); |
33 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 36 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
34 | 37 |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 for (size_t r = 0; r < arraysize(rhs_inputs); r++) { | 268 for (size_t r = 0; r < arraysize(rhs_inputs); r++) { |
266 for (size_t o = 0; o < arraysize(kShiftOperators); o++) { | 269 for (size_t o = 0; o < arraysize(kShiftOperators); o++) { |
267 HandleAndZoneScope handles; | 270 HandleAndZoneScope handles; |
268 Isolate* isolate = handles.main_isolate(); | 271 Isolate* isolate = handles.main_isolate(); |
269 Factory* factory = isolate->factory(); | 272 Factory* factory = isolate->factory(); |
270 Zone zone(isolate->allocator(), ZONE_NAME); | 273 Zone zone(isolate->allocator(), ZONE_NAME); |
271 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 1); | 274 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 1); |
272 | 275 |
273 FeedbackVectorSpec feedback_spec(&zone); | 276 FeedbackVectorSpec feedback_spec(&zone); |
274 FeedbackVectorSlot slot = feedback_spec.AddInterpreterBinaryOpICSlot(); | 277 FeedbackVectorSlot slot = feedback_spec.AddInterpreterBinaryOpICSlot(); |
275 Handle<i::TypeFeedbackVector> vector = | 278 Handle<i::TypeFeedbackMetadata> metadata = |
276 NewTypeFeedbackVector(isolate, &feedback_spec); | 279 NewTypeFeedbackMetadata(isolate, &feedback_spec); |
277 | 280 |
278 Register reg(0); | 281 Register reg(0); |
279 int lhs = lhs_inputs[l]; | 282 int lhs = lhs_inputs[l]; |
280 int rhs = rhs_inputs[r]; | 283 int rhs = rhs_inputs[r]; |
281 builder.LoadLiteral(Smi::FromInt(lhs)) | 284 builder.LoadLiteral(Smi::FromInt(lhs)) |
282 .StoreAccumulatorInRegister(reg) | 285 .StoreAccumulatorInRegister(reg) |
283 .LoadLiteral(Smi::FromInt(rhs)) | 286 .LoadLiteral(Smi::FromInt(rhs)) |
284 .BinaryOperation(kShiftOperators[o], reg, vector->GetIndex(slot)) | 287 .BinaryOperation(kShiftOperators[o], reg, GetIndex(slot)) |
285 .Return(); | 288 .Return(); |
286 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 289 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
287 | 290 |
288 InterpreterTester tester(isolate, bytecode_array, vector); | 291 InterpreterTester tester(isolate, bytecode_array, metadata); |
289 auto callable = tester.GetCallable<>(); | 292 auto callable = tester.GetCallable<>(); |
290 Handle<Object> return_value = callable().ToHandleChecked(); | 293 Handle<Object> return_value = callable().ToHandleChecked(); |
291 Handle<Object> expected_value = | 294 Handle<Object> expected_value = |
292 factory->NewNumber(BinaryOpC(kShiftOperators[o], lhs, rhs)); | 295 factory->NewNumber(BinaryOpC(kShiftOperators[o], lhs, rhs)); |
293 CHECK(return_value->SameValue(*expected_value)); | 296 CHECK(return_value->SameValue(*expected_value)); |
294 } | 297 } |
295 } | 298 } |
296 } | 299 } |
297 } | 300 } |
298 | 301 |
299 | 302 |
300 TEST(InterpreterBinaryOpsSmi) { | 303 TEST(InterpreterBinaryOpsSmi) { |
301 int lhs_inputs[] = {3266, 1024, 0, -17, -18000}; | 304 int lhs_inputs[] = {3266, 1024, 0, -17, -18000}; |
302 int rhs_inputs[] = {3266, 5, 4, 3, 2, 1, -1, -2}; | 305 int rhs_inputs[] = {3266, 5, 4, 3, 2, 1, -1, -2}; |
303 for (size_t l = 0; l < arraysize(lhs_inputs); l++) { | 306 for (size_t l = 0; l < arraysize(lhs_inputs); l++) { |
304 for (size_t r = 0; r < arraysize(rhs_inputs); r++) { | 307 for (size_t r = 0; r < arraysize(rhs_inputs); r++) { |
305 for (size_t o = 0; o < arraysize(kArithmeticOperators); o++) { | 308 for (size_t o = 0; o < arraysize(kArithmeticOperators); o++) { |
306 HandleAndZoneScope handles; | 309 HandleAndZoneScope handles; |
307 Isolate* isolate = handles.main_isolate(); | 310 Isolate* isolate = handles.main_isolate(); |
308 Factory* factory = isolate->factory(); | 311 Factory* factory = isolate->factory(); |
309 Zone zone(isolate->allocator(), ZONE_NAME); | 312 Zone zone(isolate->allocator(), ZONE_NAME); |
310 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 1); | 313 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 1); |
311 | 314 |
312 FeedbackVectorSpec feedback_spec(&zone); | 315 FeedbackVectorSpec feedback_spec(&zone); |
313 FeedbackVectorSlot slot = feedback_spec.AddInterpreterBinaryOpICSlot(); | 316 FeedbackVectorSlot slot = feedback_spec.AddInterpreterBinaryOpICSlot(); |
314 Handle<i::TypeFeedbackVector> vector = | 317 Handle<i::TypeFeedbackMetadata> metadata = |
315 NewTypeFeedbackVector(isolate, &feedback_spec); | 318 NewTypeFeedbackMetadata(isolate, &feedback_spec); |
316 | 319 |
317 Register reg(0); | 320 Register reg(0); |
318 int lhs = lhs_inputs[l]; | 321 int lhs = lhs_inputs[l]; |
319 int rhs = rhs_inputs[r]; | 322 int rhs = rhs_inputs[r]; |
320 builder.LoadLiteral(Smi::FromInt(lhs)) | 323 builder.LoadLiteral(Smi::FromInt(lhs)) |
321 .StoreAccumulatorInRegister(reg) | 324 .StoreAccumulatorInRegister(reg) |
322 .LoadLiteral(Smi::FromInt(rhs)) | 325 .LoadLiteral(Smi::FromInt(rhs)) |
323 .BinaryOperation(kArithmeticOperators[o], reg, | 326 .BinaryOperation(kArithmeticOperators[o], reg, GetIndex(slot)) |
324 vector->GetIndex(slot)) | |
325 .Return(); | 327 .Return(); |
326 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 328 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
327 | 329 |
328 InterpreterTester tester(isolate, bytecode_array, vector); | 330 InterpreterTester tester(isolate, bytecode_array, metadata); |
329 auto callable = tester.GetCallable<>(); | 331 auto callable = tester.GetCallable<>(); |
330 Handle<Object> return_value = callable().ToHandleChecked(); | 332 Handle<Object> return_value = callable().ToHandleChecked(); |
331 Handle<Object> expected_value = | 333 Handle<Object> expected_value = |
332 factory->NewNumber(BinaryOpC(kArithmeticOperators[o], lhs, rhs)); | 334 factory->NewNumber(BinaryOpC(kArithmeticOperators[o], lhs, rhs)); |
333 CHECK(return_value->SameValue(*expected_value)); | 335 CHECK(return_value->SameValue(*expected_value)); |
334 } | 336 } |
335 } | 337 } |
336 } | 338 } |
337 } | 339 } |
338 | 340 |
339 | 341 |
340 TEST(InterpreterBinaryOpsHeapNumber) { | 342 TEST(InterpreterBinaryOpsHeapNumber) { |
341 double lhs_inputs[] = {3266.101, 1024.12, 0.01, -17.99, -18000.833, 9.1e17}; | 343 double lhs_inputs[] = {3266.101, 1024.12, 0.01, -17.99, -18000.833, 9.1e17}; |
342 double rhs_inputs[] = {3266.101, 5.999, 4.778, 3.331, 2.643, | 344 double rhs_inputs[] = {3266.101, 5.999, 4.778, 3.331, 2.643, |
343 1.1, -1.8, -2.9, 8.3e-27}; | 345 1.1, -1.8, -2.9, 8.3e-27}; |
344 for (size_t l = 0; l < arraysize(lhs_inputs); l++) { | 346 for (size_t l = 0; l < arraysize(lhs_inputs); l++) { |
345 for (size_t r = 0; r < arraysize(rhs_inputs); r++) { | 347 for (size_t r = 0; r < arraysize(rhs_inputs); r++) { |
346 for (size_t o = 0; o < arraysize(kArithmeticOperators); o++) { | 348 for (size_t o = 0; o < arraysize(kArithmeticOperators); o++) { |
347 HandleAndZoneScope handles; | 349 HandleAndZoneScope handles; |
348 Isolate* isolate = handles.main_isolate(); | 350 Isolate* isolate = handles.main_isolate(); |
349 Factory* factory = isolate->factory(); | 351 Factory* factory = isolate->factory(); |
350 Zone zone(isolate->allocator(), ZONE_NAME); | 352 Zone zone(isolate->allocator(), ZONE_NAME); |
351 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 1); | 353 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 1); |
352 | 354 |
353 FeedbackVectorSpec feedback_spec(&zone); | 355 FeedbackVectorSpec feedback_spec(&zone); |
354 FeedbackVectorSlot slot = feedback_spec.AddInterpreterBinaryOpICSlot(); | 356 FeedbackVectorSlot slot = feedback_spec.AddInterpreterBinaryOpICSlot(); |
355 Handle<i::TypeFeedbackVector> vector = | 357 Handle<i::TypeFeedbackMetadata> metadata = |
356 NewTypeFeedbackVector(isolate, &feedback_spec); | 358 NewTypeFeedbackMetadata(isolate, &feedback_spec); |
357 | 359 |
358 Register reg(0); | 360 Register reg(0); |
359 double lhs = lhs_inputs[l]; | 361 double lhs = lhs_inputs[l]; |
360 double rhs = rhs_inputs[r]; | 362 double rhs = rhs_inputs[r]; |
361 builder.LoadLiteral(factory->NewNumber(lhs)) | 363 builder.LoadLiteral(factory->NewNumber(lhs)) |
362 .StoreAccumulatorInRegister(reg) | 364 .StoreAccumulatorInRegister(reg) |
363 .LoadLiteral(factory->NewNumber(rhs)) | 365 .LoadLiteral(factory->NewNumber(rhs)) |
364 .BinaryOperation(kArithmeticOperators[o], reg, | 366 .BinaryOperation(kArithmeticOperators[o], reg, GetIndex(slot)) |
365 vector->GetIndex(slot)) | |
366 .Return(); | 367 .Return(); |
367 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 368 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
368 | 369 |
369 InterpreterTester tester(isolate, bytecode_array, vector); | 370 InterpreterTester tester(isolate, bytecode_array, metadata); |
370 auto callable = tester.GetCallable<>(); | 371 auto callable = tester.GetCallable<>(); |
371 Handle<Object> return_value = callable().ToHandleChecked(); | 372 Handle<Object> return_value = callable().ToHandleChecked(); |
372 Handle<Object> expected_value = | 373 Handle<Object> expected_value = |
373 factory->NewNumber(BinaryOpC(kArithmeticOperators[o], lhs, rhs)); | 374 factory->NewNumber(BinaryOpC(kArithmeticOperators[o], lhs, rhs)); |
374 CHECK(return_value->SameValue(*expected_value)); | 375 CHECK(return_value->SameValue(*expected_value)); |
375 } | 376 } |
376 } | 377 } |
377 } | 378 } |
378 } | 379 } |
379 | 380 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 factory->NewStringFromStaticChars("-1.112.56"), | 418 factory->NewStringFromStaticChars("-1.112.56"), |
418 BinaryOperationFeedback::kAny}, | 419 BinaryOperationFeedback::kAny}, |
419 {factory->NewStringFromStaticChars(""), factory->NewHeapNumber(2.5), | 420 {factory->NewStringFromStaticChars(""), factory->NewHeapNumber(2.5), |
420 factory->NewStringFromStaticChars("2.5"), BinaryOperationFeedback::kAny}, | 421 factory->NewStringFromStaticChars("2.5"), BinaryOperationFeedback::kAny}, |
421 }; | 422 }; |
422 | 423 |
423 for (size_t i = 0; i < arraysize(test_cases); i++) { | 424 for (size_t i = 0; i < arraysize(test_cases); i++) { |
424 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 1); | 425 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 1); |
425 FeedbackVectorSpec feedback_spec(&zone); | 426 FeedbackVectorSpec feedback_spec(&zone); |
426 FeedbackVectorSlot slot = feedback_spec.AddInterpreterBinaryOpICSlot(); | 427 FeedbackVectorSlot slot = feedback_spec.AddInterpreterBinaryOpICSlot(); |
427 Handle<i::TypeFeedbackVector> vector = | 428 Handle<i::TypeFeedbackMetadata> metadata = |
428 NewTypeFeedbackVector(isolate, &feedback_spec); | 429 NewTypeFeedbackMetadata(isolate, &feedback_spec); |
429 | 430 |
430 Register reg(0); | 431 Register reg(0); |
431 builder.LoadLiteral(test_cases[i].lhs) | 432 builder.LoadLiteral(test_cases[i].lhs) |
432 .StoreAccumulatorInRegister(reg) | 433 .StoreAccumulatorInRegister(reg) |
433 .LoadLiteral(test_cases[i].rhs) | 434 .LoadLiteral(test_cases[i].rhs) |
434 .BinaryOperation(Token::Value::ADD, reg, vector->GetIndex(slot)) | 435 .BinaryOperation(Token::Value::ADD, reg, GetIndex(slot)) |
435 .Return(); | 436 .Return(); |
436 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 437 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
437 | 438 |
438 InterpreterTester tester(isolate, bytecode_array, vector); | 439 InterpreterTester tester(isolate, bytecode_array, metadata); |
439 auto callable = tester.GetCallable<>(); | 440 auto callable = tester.GetCallable<>(); |
440 Handle<Object> return_value = callable().ToHandleChecked(); | 441 Handle<Object> return_value = callable().ToHandleChecked(); |
441 CHECK(return_value->SameValue(*test_cases[i].expected_value)); | 442 CHECK(return_value->SameValue(*test_cases[i].expected_value)); |
442 | 443 |
443 Object* feedback = vector->Get(slot); | 444 Object* feedback = callable.vector()->Get(slot); |
444 CHECK(feedback->IsSmi()); | 445 CHECK(feedback->IsSmi()); |
445 CHECK_EQ(test_cases[i].expected_feedback, | 446 CHECK_EQ(test_cases[i].expected_feedback, |
446 static_cast<Smi*>(feedback)->value()); | 447 static_cast<Smi*>(feedback)->value()); |
447 } | 448 } |
448 } | 449 } |
449 | 450 |
450 | 451 |
451 TEST(InterpreterParameter1) { | 452 TEST(InterpreterParameter1) { |
452 HandleAndZoneScope handles; | 453 HandleAndZoneScope handles; |
453 Isolate* isolate = handles.main_isolate(); | 454 Isolate* isolate = handles.main_isolate(); |
(...skipping 25 matching lines...) Expand all Loading... |
479 | 480 |
480 FeedbackVectorSpec feedback_spec(&zone); | 481 FeedbackVectorSpec feedback_spec(&zone); |
481 FeedbackVectorSlot slot = feedback_spec.AddInterpreterBinaryOpICSlot(); | 482 FeedbackVectorSlot slot = feedback_spec.AddInterpreterBinaryOpICSlot(); |
482 FeedbackVectorSlot slot1 = feedback_spec.AddInterpreterBinaryOpICSlot(); | 483 FeedbackVectorSlot slot1 = feedback_spec.AddInterpreterBinaryOpICSlot(); |
483 FeedbackVectorSlot slot2 = feedback_spec.AddInterpreterBinaryOpICSlot(); | 484 FeedbackVectorSlot slot2 = feedback_spec.AddInterpreterBinaryOpICSlot(); |
484 FeedbackVectorSlot slot3 = feedback_spec.AddInterpreterBinaryOpICSlot(); | 485 FeedbackVectorSlot slot3 = feedback_spec.AddInterpreterBinaryOpICSlot(); |
485 FeedbackVectorSlot slot4 = feedback_spec.AddInterpreterBinaryOpICSlot(); | 486 FeedbackVectorSlot slot4 = feedback_spec.AddInterpreterBinaryOpICSlot(); |
486 FeedbackVectorSlot slot5 = feedback_spec.AddInterpreterBinaryOpICSlot(); | 487 FeedbackVectorSlot slot5 = feedback_spec.AddInterpreterBinaryOpICSlot(); |
487 FeedbackVectorSlot slot6 = feedback_spec.AddInterpreterBinaryOpICSlot(); | 488 FeedbackVectorSlot slot6 = feedback_spec.AddInterpreterBinaryOpICSlot(); |
488 | 489 |
489 Handle<i::TypeFeedbackVector> vector = | 490 Handle<i::TypeFeedbackMetadata> metadata = |
490 NewTypeFeedbackVector(isolate, &feedback_spec); | 491 NewTypeFeedbackMetadata(isolate, &feedback_spec); |
491 | 492 |
492 builder.LoadAccumulatorWithRegister(builder.Parameter(0)) | 493 builder.LoadAccumulatorWithRegister(builder.Parameter(0)) |
493 .BinaryOperation(Token::Value::ADD, builder.Parameter(1), | 494 .BinaryOperation(Token::Value::ADD, builder.Parameter(1), GetIndex(slot)) |
494 vector->GetIndex(slot)) | 495 .BinaryOperation(Token::Value::ADD, builder.Parameter(2), GetIndex(slot1)) |
495 .BinaryOperation(Token::Value::ADD, builder.Parameter(2), | 496 .BinaryOperation(Token::Value::ADD, builder.Parameter(3), GetIndex(slot2)) |
496 vector->GetIndex(slot1)) | 497 .BinaryOperation(Token::Value::ADD, builder.Parameter(4), GetIndex(slot3)) |
497 .BinaryOperation(Token::Value::ADD, builder.Parameter(3), | 498 .BinaryOperation(Token::Value::ADD, builder.Parameter(5), GetIndex(slot4)) |
498 vector->GetIndex(slot2)) | 499 .BinaryOperation(Token::Value::ADD, builder.Parameter(6), GetIndex(slot5)) |
499 .BinaryOperation(Token::Value::ADD, builder.Parameter(4), | 500 .BinaryOperation(Token::Value::ADD, builder.Parameter(7), GetIndex(slot6)) |
500 vector->GetIndex(slot3)) | |
501 .BinaryOperation(Token::Value::ADD, builder.Parameter(5), | |
502 vector->GetIndex(slot4)) | |
503 .BinaryOperation(Token::Value::ADD, builder.Parameter(6), | |
504 vector->GetIndex(slot5)) | |
505 .BinaryOperation(Token::Value::ADD, builder.Parameter(7), | |
506 vector->GetIndex(slot6)) | |
507 .Return(); | 501 .Return(); |
508 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 502 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
509 | 503 |
510 InterpreterTester tester(isolate, bytecode_array, vector); | 504 InterpreterTester tester(isolate, bytecode_array, metadata); |
511 typedef Handle<Object> H; | 505 typedef Handle<Object> H; |
512 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>(); |
513 | 507 |
514 Handle<Smi> arg1 = Handle<Smi>(Smi::FromInt(1), handles.main_isolate()); | 508 Handle<Smi> arg1 = Handle<Smi>(Smi::FromInt(1), handles.main_isolate()); |
515 Handle<Smi> arg2 = Handle<Smi>(Smi::FromInt(2), handles.main_isolate()); | 509 Handle<Smi> arg2 = Handle<Smi>(Smi::FromInt(2), handles.main_isolate()); |
516 Handle<Smi> arg3 = Handle<Smi>(Smi::FromInt(3), handles.main_isolate()); | 510 Handle<Smi> arg3 = Handle<Smi>(Smi::FromInt(3), handles.main_isolate()); |
517 Handle<Smi> arg4 = Handle<Smi>(Smi::FromInt(4), handles.main_isolate()); | 511 Handle<Smi> arg4 = Handle<Smi>(Smi::FromInt(4), handles.main_isolate()); |
518 Handle<Smi> arg5 = Handle<Smi>(Smi::FromInt(5), handles.main_isolate()); | 512 Handle<Smi> arg5 = Handle<Smi>(Smi::FromInt(5), handles.main_isolate()); |
519 Handle<Smi> arg6 = Handle<Smi>(Smi::FromInt(6), handles.main_isolate()); | 513 Handle<Smi> arg6 = Handle<Smi>(Smi::FromInt(6), handles.main_isolate()); |
520 Handle<Smi> arg7 = Handle<Smi>(Smi::FromInt(7), handles.main_isolate()); | 514 Handle<Smi> arg7 = Handle<Smi>(Smi::FromInt(7), handles.main_isolate()); |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
646 {Token::Value::MOD, Handle<Smi>(Smi::FromInt(3), isolate), | 640 {Token::Value::MOD, Handle<Smi>(Smi::FromInt(3), isolate), |
647 isolate->factory()->NewStringFromAsciiChecked("-2"), | 641 isolate->factory()->NewStringFromAsciiChecked("-2"), |
648 Handle<Smi>(Smi::FromInt(1), isolate), BinaryOperationFeedback::kAny}}; | 642 Handle<Smi>(Smi::FromInt(1), isolate), BinaryOperationFeedback::kAny}}; |
649 | 643 |
650 for (const BinaryOpExpectation& test_case : kTestCases) { | 644 for (const BinaryOpExpectation& test_case : kTestCases) { |
651 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 1); | 645 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 1); |
652 | 646 |
653 i::FeedbackVectorSpec feedback_spec(&zone); | 647 i::FeedbackVectorSpec feedback_spec(&zone); |
654 i::FeedbackVectorSlot slot0 = feedback_spec.AddInterpreterBinaryOpICSlot(); | 648 i::FeedbackVectorSlot slot0 = feedback_spec.AddInterpreterBinaryOpICSlot(); |
655 | 649 |
656 Handle<i::TypeFeedbackVector> vector = | 650 Handle<i::TypeFeedbackMetadata> metadata = |
657 i::NewTypeFeedbackVector(isolate, &feedback_spec); | 651 i::NewTypeFeedbackMetadata(isolate, &feedback_spec); |
658 | 652 |
659 Register reg(0); | 653 Register reg(0); |
660 builder.LoadLiteral(test_case.arg1) | 654 builder.LoadLiteral(test_case.arg1) |
661 .StoreAccumulatorInRegister(reg) | 655 .StoreAccumulatorInRegister(reg) |
662 .LoadLiteral(test_case.arg2) | 656 .LoadLiteral(test_case.arg2) |
663 .BinaryOperation(test_case.op, reg, vector->GetIndex(slot0)) | 657 .BinaryOperation(test_case.op, reg, GetIndex(slot0)) |
664 .Return(); | 658 .Return(); |
665 | 659 |
666 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 660 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
667 | 661 |
668 InterpreterTester tester(isolate, bytecode_array, vector); | 662 InterpreterTester tester(isolate, bytecode_array, metadata); |
669 auto callable = tester.GetCallable<>(); | 663 auto callable = tester.GetCallable<>(); |
670 | 664 |
671 Handle<Object> return_val = callable().ToHandleChecked(); | 665 Handle<Object> return_val = callable().ToHandleChecked(); |
672 Object* feedback0 = vector->Get(slot0); | 666 Object* feedback0 = callable.vector()->Get(slot0); |
673 CHECK(feedback0->IsSmi()); | 667 CHECK(feedback0->IsSmi()); |
674 CHECK_EQ(test_case.feedback, static_cast<Smi*>(feedback0)->value()); | 668 CHECK_EQ(test_case.feedback, static_cast<Smi*>(feedback0)->value()); |
675 CHECK(Object::Equals(test_case.result, return_val).ToChecked()); | 669 CHECK(Object::Equals(test_case.result, return_val).ToChecked()); |
676 } | 670 } |
677 } | 671 } |
678 | 672 |
679 TEST(InterpreterBinaryOpSmiTypeFeedback) { | 673 TEST(InterpreterBinaryOpSmiTypeFeedback) { |
680 HandleAndZoneScope handles; | 674 HandleAndZoneScope handles; |
681 i::Isolate* isolate = handles.main_isolate(); | 675 i::Isolate* isolate = handles.main_isolate(); |
682 i::Zone zone(isolate->allocator(), ZONE_NAME); | 676 i::Zone zone(isolate->allocator(), ZONE_NAME); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
750 Handle<Smi>(Smi::kZero, isolate), BinaryOperationFeedback::kNumber}, | 744 Handle<Smi>(Smi::kZero, isolate), BinaryOperationFeedback::kNumber}, |
751 {Token::Value::SAR, isolate->factory()->NewStringFromAsciiChecked("2"), 1, | 745 {Token::Value::SAR, isolate->factory()->NewStringFromAsciiChecked("2"), 1, |
752 Handle<Smi>(Smi::FromInt(1), isolate), BinaryOperationFeedback::kAny}}; | 746 Handle<Smi>(Smi::FromInt(1), isolate), BinaryOperationFeedback::kAny}}; |
753 | 747 |
754 for (const BinaryOpExpectation& test_case : kTestCases) { | 748 for (const BinaryOpExpectation& test_case : kTestCases) { |
755 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 1); | 749 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 1); |
756 | 750 |
757 i::FeedbackVectorSpec feedback_spec(&zone); | 751 i::FeedbackVectorSpec feedback_spec(&zone); |
758 i::FeedbackVectorSlot slot0 = feedback_spec.AddInterpreterBinaryOpICSlot(); | 752 i::FeedbackVectorSlot slot0 = feedback_spec.AddInterpreterBinaryOpICSlot(); |
759 | 753 |
760 Handle<i::TypeFeedbackVector> vector = | 754 Handle<i::TypeFeedbackMetadata> metadata = |
761 i::NewTypeFeedbackVector(isolate, &feedback_spec); | 755 i::NewTypeFeedbackMetadata(isolate, &feedback_spec); |
762 | 756 |
763 Register reg(0); | 757 Register reg(0); |
764 builder.LoadLiteral(test_case.arg1) | 758 builder.LoadLiteral(test_case.arg1) |
765 .StoreAccumulatorInRegister(reg) | 759 .StoreAccumulatorInRegister(reg) |
766 .LoadLiteral(Smi::FromInt(test_case.arg2)) | 760 .LoadLiteral(Smi::FromInt(test_case.arg2)) |
767 .BinaryOperation(test_case.op, reg, vector->GetIndex(slot0)) | 761 .BinaryOperation(test_case.op, reg, GetIndex(slot0)) |
768 .Return(); | 762 .Return(); |
769 | 763 |
770 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 764 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
771 | 765 |
772 InterpreterTester tester(isolate, bytecode_array, vector); | 766 InterpreterTester tester(isolate, bytecode_array, metadata); |
773 auto callable = tester.GetCallable<>(); | 767 auto callable = tester.GetCallable<>(); |
774 | 768 |
775 Handle<Object> return_val = callable().ToHandleChecked(); | 769 Handle<Object> return_val = callable().ToHandleChecked(); |
776 Object* feedback0 = vector->Get(slot0); | 770 Object* feedback0 = callable.vector()->Get(slot0); |
777 CHECK(feedback0->IsSmi()); | 771 CHECK(feedback0->IsSmi()); |
778 CHECK_EQ(test_case.feedback, static_cast<Smi*>(feedback0)->value()); | 772 CHECK_EQ(test_case.feedback, static_cast<Smi*>(feedback0)->value()); |
779 CHECK(Object::Equals(test_case.result, return_val).ToChecked()); | 773 CHECK(Object::Equals(test_case.result, return_val).ToChecked()); |
780 } | 774 } |
781 } | 775 } |
782 | 776 |
783 TEST(InterpreterUnaryOpFeedback) { | 777 TEST(InterpreterUnaryOpFeedback) { |
784 HandleAndZoneScope handles; | 778 HandleAndZoneScope handles; |
785 i::Isolate* isolate = handles.main_isolate(); | 779 i::Isolate* isolate = handles.main_isolate(); |
786 i::Zone zone(isolate->allocator(), ZONE_NAME); | 780 i::Zone zone(isolate->allocator(), ZONE_NAME); |
(...skipping 16 matching lines...) Expand all Loading... |
803 {Token::Value::SUB, smi_one, smi_min, number, str}}; | 797 {Token::Value::SUB, smi_one, smi_min, number, str}}; |
804 for (TestCase const& test_case : kTestCases) { | 798 for (TestCase const& test_case : kTestCases) { |
805 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 4, 0, 0); | 799 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 4, 0, 0); |
806 | 800 |
807 i::FeedbackVectorSpec feedback_spec(&zone); | 801 i::FeedbackVectorSpec feedback_spec(&zone); |
808 i::FeedbackVectorSlot slot0 = feedback_spec.AddInterpreterBinaryOpICSlot(); | 802 i::FeedbackVectorSlot slot0 = feedback_spec.AddInterpreterBinaryOpICSlot(); |
809 i::FeedbackVectorSlot slot1 = feedback_spec.AddInterpreterBinaryOpICSlot(); | 803 i::FeedbackVectorSlot slot1 = feedback_spec.AddInterpreterBinaryOpICSlot(); |
810 i::FeedbackVectorSlot slot2 = feedback_spec.AddInterpreterBinaryOpICSlot(); | 804 i::FeedbackVectorSlot slot2 = feedback_spec.AddInterpreterBinaryOpICSlot(); |
811 i::FeedbackVectorSlot slot3 = feedback_spec.AddInterpreterBinaryOpICSlot(); | 805 i::FeedbackVectorSlot slot3 = feedback_spec.AddInterpreterBinaryOpICSlot(); |
812 | 806 |
813 Handle<i::TypeFeedbackVector> vector = | 807 Handle<i::TypeFeedbackMetadata> metadata = |
814 i::NewTypeFeedbackVector(isolate, &feedback_spec); | 808 i::NewTypeFeedbackMetadata(isolate, &feedback_spec); |
815 | 809 |
816 builder.LoadAccumulatorWithRegister(builder.Parameter(0)) | 810 builder.LoadAccumulatorWithRegister(builder.Parameter(0)) |
817 .CountOperation(test_case.op, vector->GetIndex(slot0)) | 811 .CountOperation(test_case.op, GetIndex(slot0)) |
818 .LoadAccumulatorWithRegister(builder.Parameter(1)) | 812 .LoadAccumulatorWithRegister(builder.Parameter(1)) |
819 .CountOperation(test_case.op, vector->GetIndex(slot1)) | 813 .CountOperation(test_case.op, GetIndex(slot1)) |
820 .LoadAccumulatorWithRegister(builder.Parameter(2)) | 814 .LoadAccumulatorWithRegister(builder.Parameter(2)) |
821 .CountOperation(test_case.op, vector->GetIndex(slot2)) | 815 .CountOperation(test_case.op, GetIndex(slot2)) |
822 .LoadAccumulatorWithRegister(builder.Parameter(3)) | 816 .LoadAccumulatorWithRegister(builder.Parameter(3)) |
823 .CountOperation(test_case.op, vector->GetIndex(slot3)) | 817 .CountOperation(test_case.op, GetIndex(slot3)) |
824 .Return(); | 818 .Return(); |
825 | 819 |
826 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 820 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
827 | 821 |
828 InterpreterTester tester(isolate, bytecode_array, vector); | 822 InterpreterTester tester(isolate, bytecode_array, metadata); |
829 typedef Handle<Object> H; | 823 typedef Handle<Object> H; |
830 auto callable = tester.GetCallable<H, H, H, H>(); | 824 auto callable = tester.GetCallable<H, H, H, H>(); |
831 | 825 |
832 Handle<Object> return_val = | 826 Handle<Object> return_val = |
833 callable(test_case.smi_feedback_value, | 827 callable(test_case.smi_feedback_value, |
834 test_case.smi_to_number_feedback_value, | 828 test_case.smi_to_number_feedback_value, |
835 test_case.number_feedback_value, test_case.any_feedback_value) | 829 test_case.number_feedback_value, test_case.any_feedback_value) |
836 .ToHandleChecked(); | 830 .ToHandleChecked(); |
837 USE(return_val); | 831 USE(return_val); |
838 Object* feedback0 = vector->Get(slot0); | 832 Object* feedback0 = callable.vector()->Get(slot0); |
839 CHECK(feedback0->IsSmi()); | 833 CHECK(feedback0->IsSmi()); |
840 CHECK_EQ(BinaryOperationFeedback::kSignedSmall, | 834 CHECK_EQ(BinaryOperationFeedback::kSignedSmall, |
841 static_cast<Smi*>(feedback0)->value()); | 835 static_cast<Smi*>(feedback0)->value()); |
842 | 836 |
843 Object* feedback1 = vector->Get(slot1); | 837 Object* feedback1 = callable.vector()->Get(slot1); |
844 CHECK(feedback1->IsSmi()); | 838 CHECK(feedback1->IsSmi()); |
845 CHECK_EQ(BinaryOperationFeedback::kNumber, | 839 CHECK_EQ(BinaryOperationFeedback::kNumber, |
846 static_cast<Smi*>(feedback1)->value()); | 840 static_cast<Smi*>(feedback1)->value()); |
847 | 841 |
848 Object* feedback2 = vector->Get(slot2); | 842 Object* feedback2 = callable.vector()->Get(slot2); |
849 CHECK(feedback2->IsSmi()); | 843 CHECK(feedback2->IsSmi()); |
850 CHECK_EQ(BinaryOperationFeedback::kNumber, | 844 CHECK_EQ(BinaryOperationFeedback::kNumber, |
851 static_cast<Smi*>(feedback2)->value()); | 845 static_cast<Smi*>(feedback2)->value()); |
852 | 846 |
853 Object* feedback3 = vector->Get(slot3); | 847 Object* feedback3 = callable.vector()->Get(slot3); |
854 CHECK(feedback3->IsSmi()); | 848 CHECK(feedback3->IsSmi()); |
855 CHECK_EQ(BinaryOperationFeedback::kAny, | 849 CHECK_EQ(BinaryOperationFeedback::kAny, |
856 static_cast<Smi*>(feedback3)->value()); | 850 static_cast<Smi*>(feedback3)->value()); |
857 } | 851 } |
858 } | 852 } |
859 | 853 |
860 TEST(InterpreterBitwiseTypeFeedback) { | 854 TEST(InterpreterBitwiseTypeFeedback) { |
861 HandleAndZoneScope handles; | 855 HandleAndZoneScope handles; |
862 i::Isolate* isolate = handles.main_isolate(); | 856 i::Isolate* isolate = handles.main_isolate(); |
863 i::Zone zone(isolate->allocator(), ZONE_NAME); | 857 i::Zone zone(isolate->allocator(), ZONE_NAME); |
864 const Token::Value kBitwiseBinaryOperators[] = { | 858 const Token::Value kBitwiseBinaryOperators[] = { |
865 Token::Value::BIT_OR, Token::Value::BIT_XOR, Token::Value::BIT_AND, | 859 Token::Value::BIT_OR, Token::Value::BIT_XOR, Token::Value::BIT_AND, |
866 Token::Value::SHL, Token::Value::SHR, Token::Value::SAR}; | 860 Token::Value::SHL, Token::Value::SHR, Token::Value::SAR}; |
867 | 861 |
868 for (Token::Value op : kBitwiseBinaryOperators) { | 862 for (Token::Value op : kBitwiseBinaryOperators) { |
869 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 4, 0, 0); | 863 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 4, 0, 0); |
870 | 864 |
871 i::FeedbackVectorSpec feedback_spec(&zone); | 865 i::FeedbackVectorSpec feedback_spec(&zone); |
872 i::FeedbackVectorSlot slot0 = feedback_spec.AddInterpreterBinaryOpICSlot(); | 866 i::FeedbackVectorSlot slot0 = feedback_spec.AddInterpreterBinaryOpICSlot(); |
873 i::FeedbackVectorSlot slot1 = feedback_spec.AddInterpreterBinaryOpICSlot(); | 867 i::FeedbackVectorSlot slot1 = feedback_spec.AddInterpreterBinaryOpICSlot(); |
874 i::FeedbackVectorSlot slot2 = feedback_spec.AddInterpreterBinaryOpICSlot(); | 868 i::FeedbackVectorSlot slot2 = feedback_spec.AddInterpreterBinaryOpICSlot(); |
875 | 869 |
876 Handle<i::TypeFeedbackVector> vector = | 870 Handle<i::TypeFeedbackMetadata> metadata = |
877 i::NewTypeFeedbackVector(isolate, &feedback_spec); | 871 i::NewTypeFeedbackMetadata(isolate, &feedback_spec); |
878 | 872 |
879 builder.LoadAccumulatorWithRegister(builder.Parameter(0)) | 873 builder.LoadAccumulatorWithRegister(builder.Parameter(0)) |
880 .BinaryOperation(op, builder.Parameter(1), vector->GetIndex(slot0)) | 874 .BinaryOperation(op, builder.Parameter(1), GetIndex(slot0)) |
881 .BinaryOperation(op, builder.Parameter(2), vector->GetIndex(slot1)) | 875 .BinaryOperation(op, builder.Parameter(2), GetIndex(slot1)) |
882 .BinaryOperation(op, builder.Parameter(3), vector->GetIndex(slot2)) | 876 .BinaryOperation(op, builder.Parameter(3), GetIndex(slot2)) |
883 .Return(); | 877 .Return(); |
884 | 878 |
885 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 879 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
886 | 880 |
887 InterpreterTester tester(isolate, bytecode_array, vector); | 881 InterpreterTester tester(isolate, bytecode_array, metadata); |
888 typedef Handle<Object> H; | 882 typedef Handle<Object> H; |
889 auto callable = tester.GetCallable<H, H, H, H>(); | 883 auto callable = tester.GetCallable<H, H, H, H>(); |
890 | 884 |
891 Handle<Smi> arg1 = Handle<Smi>(Smi::FromInt(2), isolate); | 885 Handle<Smi> arg1 = Handle<Smi>(Smi::FromInt(2), isolate); |
892 Handle<Smi> arg2 = Handle<Smi>(Smi::FromInt(2), isolate); | 886 Handle<Smi> arg2 = Handle<Smi>(Smi::FromInt(2), isolate); |
893 Handle<HeapNumber> arg3 = isolate->factory()->NewHeapNumber(2.2); | 887 Handle<HeapNumber> arg3 = isolate->factory()->NewHeapNumber(2.2); |
894 Handle<String> arg4 = isolate->factory()->NewStringFromAsciiChecked("2"); | 888 Handle<String> arg4 = isolate->factory()->NewStringFromAsciiChecked("2"); |
895 | 889 |
896 Handle<Object> return_val = | 890 Handle<Object> return_val = |
897 callable(arg1, arg2, arg3, arg4).ToHandleChecked(); | 891 callable(arg1, arg2, arg3, arg4).ToHandleChecked(); |
898 USE(return_val); | 892 USE(return_val); |
899 Object* feedback0 = vector->Get(slot0); | 893 Object* feedback0 = callable.vector()->Get(slot0); |
900 CHECK(feedback0->IsSmi()); | 894 CHECK(feedback0->IsSmi()); |
901 CHECK_EQ(BinaryOperationFeedback::kSignedSmall, | 895 CHECK_EQ(BinaryOperationFeedback::kSignedSmall, |
902 static_cast<Smi*>(feedback0)->value()); | 896 static_cast<Smi*>(feedback0)->value()); |
903 | 897 |
904 Object* feedback1 = vector->Get(slot1); | 898 Object* feedback1 = callable.vector()->Get(slot1); |
905 CHECK(feedback1->IsSmi()); | 899 CHECK(feedback1->IsSmi()); |
906 CHECK_EQ(BinaryOperationFeedback::kNumber, | 900 CHECK_EQ(BinaryOperationFeedback::kNumber, |
907 static_cast<Smi*>(feedback1)->value()); | 901 static_cast<Smi*>(feedback1)->value()); |
908 | 902 |
909 Object* feedback2 = vector->Get(slot2); | 903 Object* feedback2 = callable.vector()->Get(slot2); |
910 CHECK(feedback2->IsSmi()); | 904 CHECK(feedback2->IsSmi()); |
911 CHECK_EQ(BinaryOperationFeedback::kAny, | 905 CHECK_EQ(BinaryOperationFeedback::kAny, |
912 static_cast<Smi*>(feedback2)->value()); | 906 static_cast<Smi*>(feedback2)->value()); |
913 } | 907 } |
914 } | 908 } |
915 | 909 |
916 TEST(InterpreterParameter1Assign) { | 910 TEST(InterpreterParameter1Assign) { |
917 HandleAndZoneScope handles; | 911 HandleAndZoneScope handles; |
918 Isolate* isolate = handles.main_isolate(); | 912 Isolate* isolate = handles.main_isolate(); |
919 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 0); | 913 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 0); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1034 | 1028 |
1035 TEST(InterpreterLoadNamedProperty) { | 1029 TEST(InterpreterLoadNamedProperty) { |
1036 HandleAndZoneScope handles; | 1030 HandleAndZoneScope handles; |
1037 Isolate* isolate = handles.main_isolate(); | 1031 Isolate* isolate = handles.main_isolate(); |
1038 Factory* factory = isolate->factory(); | 1032 Factory* factory = isolate->factory(); |
1039 Zone zone(isolate->allocator(), ZONE_NAME); | 1033 Zone zone(isolate->allocator(), ZONE_NAME); |
1040 | 1034 |
1041 FeedbackVectorSpec feedback_spec(&zone); | 1035 FeedbackVectorSpec feedback_spec(&zone); |
1042 FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot(); | 1036 FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot(); |
1043 | 1037 |
1044 Handle<i::TypeFeedbackVector> vector = | 1038 Handle<i::TypeFeedbackMetadata> metadata = |
1045 NewTypeFeedbackVector(isolate, &feedback_spec); | 1039 NewTypeFeedbackMetadata(isolate, &feedback_spec); |
1046 | 1040 |
1047 Handle<i::String> name = factory->NewStringFromAsciiChecked("val"); | 1041 Handle<i::String> name = factory->NewStringFromAsciiChecked("val"); |
1048 name = factory->string_table()->LookupString(isolate, name); | 1042 name = factory->string_table()->LookupString(isolate, name); |
1049 | 1043 |
1050 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 0); | 1044 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 0); |
1051 | 1045 |
1052 builder.LoadNamedProperty(builder.Parameter(0), name, vector->GetIndex(slot)) | 1046 builder.LoadNamedProperty(builder.Parameter(0), name, GetIndex(slot)) |
1053 .Return(); | 1047 .Return(); |
1054 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 1048 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
1055 | 1049 |
1056 InterpreterTester tester(isolate, bytecode_array, vector); | 1050 InterpreterTester tester(isolate, bytecode_array, metadata); |
1057 auto callable = tester.GetCallable<Handle<Object>>(); | 1051 auto callable = tester.GetCallable<Handle<Object>>(); |
1058 | 1052 |
1059 Handle<Object> object = InterpreterTester::NewObject("({ val : 123 })"); | 1053 Handle<Object> object = InterpreterTester::NewObject("({ val : 123 })"); |
1060 // Test IC miss. | 1054 // Test IC miss. |
1061 Handle<Object> return_val = callable(object).ToHandleChecked(); | 1055 Handle<Object> return_val = callable(object).ToHandleChecked(); |
1062 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(123)); | 1056 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(123)); |
1063 | 1057 |
1064 // Test transition to monomorphic IC. | 1058 // Test transition to monomorphic IC. |
1065 return_val = callable(object).ToHandleChecked(); | 1059 return_val = callable(object).ToHandleChecked(); |
1066 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(123)); | 1060 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(123)); |
(...skipping 20 matching lines...) Expand all Loading... |
1087 | 1081 |
1088 TEST(InterpreterLoadKeyedProperty) { | 1082 TEST(InterpreterLoadKeyedProperty) { |
1089 HandleAndZoneScope handles; | 1083 HandleAndZoneScope handles; |
1090 Isolate* isolate = handles.main_isolate(); | 1084 Isolate* isolate = handles.main_isolate(); |
1091 Factory* factory = isolate->factory(); | 1085 Factory* factory = isolate->factory(); |
1092 Zone zone(isolate->allocator(), ZONE_NAME); | 1086 Zone zone(isolate->allocator(), ZONE_NAME); |
1093 | 1087 |
1094 FeedbackVectorSpec feedback_spec(&zone); | 1088 FeedbackVectorSpec feedback_spec(&zone); |
1095 FeedbackVectorSlot slot = feedback_spec.AddKeyedLoadICSlot(); | 1089 FeedbackVectorSlot slot = feedback_spec.AddKeyedLoadICSlot(); |
1096 | 1090 |
1097 Handle<i::TypeFeedbackVector> vector = | 1091 Handle<i::TypeFeedbackMetadata> metadata = |
1098 NewTypeFeedbackVector(isolate, &feedback_spec); | 1092 NewTypeFeedbackMetadata(isolate, &feedback_spec); |
1099 | 1093 |
1100 Handle<i::String> key = factory->NewStringFromAsciiChecked("key"); | 1094 Handle<i::String> key = factory->NewStringFromAsciiChecked("key"); |
1101 key = factory->string_table()->LookupString(isolate, key); | 1095 key = factory->string_table()->LookupString(isolate, key); |
1102 | 1096 |
1103 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 1); | 1097 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 1); |
1104 | 1098 |
1105 builder.LoadLiteral(key) | 1099 builder.LoadLiteral(key) |
1106 .LoadKeyedProperty(builder.Parameter(0), vector->GetIndex(slot)) | 1100 .LoadKeyedProperty(builder.Parameter(0), GetIndex(slot)) |
1107 .Return(); | 1101 .Return(); |
1108 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 1102 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
1109 | 1103 |
1110 InterpreterTester tester(isolate, bytecode_array, vector); | 1104 InterpreterTester tester(isolate, bytecode_array, metadata); |
1111 auto callable = tester.GetCallable<Handle<Object>>(); | 1105 auto callable = tester.GetCallable<Handle<Object>>(); |
1112 | 1106 |
1113 Handle<Object> object = InterpreterTester::NewObject("({ key : 123 })"); | 1107 Handle<Object> object = InterpreterTester::NewObject("({ key : 123 })"); |
1114 // Test IC miss. | 1108 // Test IC miss. |
1115 Handle<Object> return_val = callable(object).ToHandleChecked(); | 1109 Handle<Object> return_val = callable(object).ToHandleChecked(); |
1116 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(123)); | 1110 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(123)); |
1117 | 1111 |
1118 // Test transition to monomorphic IC. | 1112 // Test transition to monomorphic IC. |
1119 return_val = callable(object).ToHandleChecked(); | 1113 return_val = callable(object).ToHandleChecked(); |
1120 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(123)); | 1114 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(123)); |
1121 | 1115 |
1122 // Test transition to megamorphic IC. | 1116 // Test transition to megamorphic IC. |
1123 Handle<Object> object3 = | 1117 Handle<Object> object3 = |
1124 InterpreterTester::NewObject("({ key : 789, val2 : 123 })"); | 1118 InterpreterTester::NewObject("({ key : 789, val2 : 123 })"); |
1125 return_val = callable(object3).ToHandleChecked(); | 1119 return_val = callable(object3).ToHandleChecked(); |
1126 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(789)); | 1120 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(789)); |
1127 } | 1121 } |
1128 | 1122 |
1129 | 1123 |
1130 TEST(InterpreterStoreNamedProperty) { | 1124 TEST(InterpreterStoreNamedProperty) { |
1131 HandleAndZoneScope handles; | 1125 HandleAndZoneScope handles; |
1132 Isolate* isolate = handles.main_isolate(); | 1126 Isolate* isolate = handles.main_isolate(); |
1133 Factory* factory = isolate->factory(); | 1127 Factory* factory = isolate->factory(); |
1134 Zone zone(isolate->allocator(), ZONE_NAME); | 1128 Zone zone(isolate->allocator(), ZONE_NAME); |
1135 | 1129 |
1136 FeedbackVectorSpec feedback_spec(&zone); | 1130 FeedbackVectorSpec feedback_spec(&zone); |
1137 FeedbackVectorSlot slot = feedback_spec.AddStoreICSlot(); | 1131 FeedbackVectorSlot slot = feedback_spec.AddStoreICSlot(); |
1138 | 1132 |
1139 Handle<i::TypeFeedbackVector> vector = | 1133 Handle<i::TypeFeedbackMetadata> metadata = |
1140 NewTypeFeedbackVector(isolate, &feedback_spec); | 1134 NewTypeFeedbackMetadata(isolate, &feedback_spec); |
1141 | 1135 |
1142 Handle<i::String> name = factory->NewStringFromAsciiChecked("val"); | 1136 Handle<i::String> name = factory->NewStringFromAsciiChecked("val"); |
1143 name = factory->string_table()->LookupString(isolate, name); | 1137 name = factory->string_table()->LookupString(isolate, name); |
1144 | 1138 |
1145 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 0); | 1139 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 0); |
1146 | 1140 |
1147 builder.LoadLiteral(Smi::FromInt(999)) | 1141 builder.LoadLiteral(Smi::FromInt(999)) |
1148 .StoreNamedProperty(builder.Parameter(0), name, vector->GetIndex(slot), | 1142 .StoreNamedProperty(builder.Parameter(0), name, GetIndex(slot), STRICT) |
1149 STRICT) | |
1150 .Return(); | 1143 .Return(); |
1151 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 1144 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
1152 | 1145 |
1153 InterpreterTester tester(isolate, bytecode_array, vector); | 1146 InterpreterTester tester(isolate, bytecode_array, metadata); |
1154 auto callable = tester.GetCallable<Handle<Object>>(); | 1147 auto callable = tester.GetCallable<Handle<Object>>(); |
1155 Handle<Object> object = InterpreterTester::NewObject("({ val : 123 })"); | 1148 Handle<Object> object = InterpreterTester::NewObject("({ val : 123 })"); |
1156 // Test IC miss. | 1149 // Test IC miss. |
1157 Handle<Object> result; | 1150 Handle<Object> result; |
1158 callable(object).ToHandleChecked(); | 1151 callable(object).ToHandleChecked(); |
1159 CHECK(Runtime::GetObjectProperty(isolate, object, name).ToHandle(&result)); | 1152 CHECK(Runtime::GetObjectProperty(isolate, object, name).ToHandle(&result)); |
1160 CHECK_EQ(Smi::cast(*result), Smi::FromInt(999)); | 1153 CHECK_EQ(Smi::cast(*result), Smi::FromInt(999)); |
1161 | 1154 |
1162 // Test transition to monomorphic IC. | 1155 // Test transition to monomorphic IC. |
1163 callable(object).ToHandleChecked(); | 1156 callable(object).ToHandleChecked(); |
(...skipping 24 matching lines...) Expand all Loading... |
1188 | 1181 |
1189 TEST(InterpreterStoreKeyedProperty) { | 1182 TEST(InterpreterStoreKeyedProperty) { |
1190 HandleAndZoneScope handles; | 1183 HandleAndZoneScope handles; |
1191 Isolate* isolate = handles.main_isolate(); | 1184 Isolate* isolate = handles.main_isolate(); |
1192 Factory* factory = isolate->factory(); | 1185 Factory* factory = isolate->factory(); |
1193 Zone zone(isolate->allocator(), ZONE_NAME); | 1186 Zone zone(isolate->allocator(), ZONE_NAME); |
1194 | 1187 |
1195 FeedbackVectorSpec feedback_spec(&zone); | 1188 FeedbackVectorSpec feedback_spec(&zone); |
1196 FeedbackVectorSlot slot = feedback_spec.AddKeyedStoreICSlot(); | 1189 FeedbackVectorSlot slot = feedback_spec.AddKeyedStoreICSlot(); |
1197 | 1190 |
1198 Handle<i::TypeFeedbackVector> vector = | 1191 Handle<i::TypeFeedbackMetadata> metadata = |
1199 NewTypeFeedbackVector(isolate, &feedback_spec); | 1192 NewTypeFeedbackMetadata(isolate, &feedback_spec); |
1200 | 1193 |
1201 Handle<i::String> name = factory->NewStringFromAsciiChecked("val"); | 1194 Handle<i::String> name = factory->NewStringFromAsciiChecked("val"); |
1202 name = factory->string_table()->LookupString(isolate, name); | 1195 name = factory->string_table()->LookupString(isolate, name); |
1203 | 1196 |
1204 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 1); | 1197 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 1); |
1205 | 1198 |
1206 builder.LoadLiteral(name) | 1199 builder.LoadLiteral(name) |
1207 .StoreAccumulatorInRegister(Register(0)) | 1200 .StoreAccumulatorInRegister(Register(0)) |
1208 .LoadLiteral(Smi::FromInt(999)) | 1201 .LoadLiteral(Smi::FromInt(999)) |
1209 .StoreKeyedProperty(builder.Parameter(0), Register(0), | 1202 .StoreKeyedProperty(builder.Parameter(0), Register(0), GetIndex(slot), |
1210 vector->GetIndex(slot), i::SLOPPY) | 1203 i::SLOPPY) |
1211 .Return(); | 1204 .Return(); |
1212 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 1205 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
1213 | 1206 |
1214 InterpreterTester tester(isolate, bytecode_array, vector); | 1207 InterpreterTester tester(isolate, bytecode_array, metadata); |
1215 auto callable = tester.GetCallable<Handle<Object>>(); | 1208 auto callable = tester.GetCallable<Handle<Object>>(); |
1216 Handle<Object> object = InterpreterTester::NewObject("({ val : 123 })"); | 1209 Handle<Object> object = InterpreterTester::NewObject("({ val : 123 })"); |
1217 // Test IC miss. | 1210 // Test IC miss. |
1218 Handle<Object> result; | 1211 Handle<Object> result; |
1219 callable(object).ToHandleChecked(); | 1212 callable(object).ToHandleChecked(); |
1220 CHECK(Runtime::GetObjectProperty(isolate, object, name).ToHandle(&result)); | 1213 CHECK(Runtime::GetObjectProperty(isolate, object, name).ToHandle(&result)); |
1221 CHECK_EQ(Smi::cast(*result), Smi::FromInt(999)); | 1214 CHECK_EQ(Smi::cast(*result), Smi::FromInt(999)); |
1222 | 1215 |
1223 // Test transition to monomorphic IC. | 1216 // Test transition to monomorphic IC. |
1224 callable(object).ToHandleChecked(); | 1217 callable(object).ToHandleChecked(); |
(...skipping 11 matching lines...) Expand all Loading... |
1236 static void TestInterpreterCall(TailCallMode tail_call_mode) { | 1229 static void TestInterpreterCall(TailCallMode tail_call_mode) { |
1237 HandleAndZoneScope handles; | 1230 HandleAndZoneScope handles; |
1238 Isolate* isolate = handles.main_isolate(); | 1231 Isolate* isolate = handles.main_isolate(); |
1239 Factory* factory = isolate->factory(); | 1232 Factory* factory = isolate->factory(); |
1240 Zone zone(isolate->allocator(), ZONE_NAME); | 1233 Zone zone(isolate->allocator(), ZONE_NAME); |
1241 | 1234 |
1242 FeedbackVectorSpec feedback_spec(&zone); | 1235 FeedbackVectorSpec feedback_spec(&zone); |
1243 FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot(); | 1236 FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot(); |
1244 FeedbackVectorSlot call_slot = feedback_spec.AddCallICSlot(); | 1237 FeedbackVectorSlot call_slot = feedback_spec.AddCallICSlot(); |
1245 | 1238 |
1246 Handle<i::TypeFeedbackVector> vector = | 1239 Handle<i::TypeFeedbackMetadata> metadata = |
1247 NewTypeFeedbackVector(isolate, &feedback_spec); | 1240 NewTypeFeedbackMetadata(isolate, &feedback_spec); |
1248 int slot_index = vector->GetIndex(slot); | 1241 int slot_index = GetIndex(slot); |
1249 int call_slot_index = -1; | 1242 int call_slot_index = -1; |
1250 call_slot_index = vector->GetIndex(call_slot); | 1243 call_slot_index = GetIndex(call_slot); |
1251 | 1244 |
1252 Handle<i::String> name = factory->NewStringFromAsciiChecked("func"); | 1245 Handle<i::String> name = factory->NewStringFromAsciiChecked("func"); |
1253 name = factory->string_table()->LookupString(isolate, name); | 1246 name = factory->string_table()->LookupString(isolate, name); |
1254 | 1247 |
1255 // Check with no args. | 1248 // Check with no args. |
1256 { | 1249 { |
1257 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 1); | 1250 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 1); |
1258 Register reg = builder.register_allocator()->NewRegister(); | 1251 Register reg = builder.register_allocator()->NewRegister(); |
1259 RegisterList args = builder.register_allocator()->NewRegisterList(1); | 1252 RegisterList args = builder.register_allocator()->NewRegisterList(1); |
1260 builder.LoadNamedProperty(builder.Parameter(0), name, slot_index) | 1253 builder.LoadNamedProperty(builder.Parameter(0), name, slot_index) |
1261 .StoreAccumulatorInRegister(reg) | 1254 .StoreAccumulatorInRegister(reg) |
1262 .MoveRegister(builder.Parameter(0), args[0]); | 1255 .MoveRegister(builder.Parameter(0), args[0]); |
1263 | 1256 |
1264 builder.Call(reg, args, call_slot_index, Call::GLOBAL_CALL, tail_call_mode); | 1257 builder.Call(reg, args, call_slot_index, Call::GLOBAL_CALL, tail_call_mode); |
1265 | 1258 |
1266 builder.Return(); | 1259 builder.Return(); |
1267 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 1260 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
1268 | 1261 |
1269 InterpreterTester tester(isolate, bytecode_array, vector); | 1262 InterpreterTester tester(isolate, bytecode_array, metadata); |
1270 auto callable = tester.GetCallable<Handle<Object>>(); | 1263 auto callable = tester.GetCallable<Handle<Object>>(); |
1271 | 1264 |
1272 Handle<Object> object = InterpreterTester::NewObject( | 1265 Handle<Object> object = InterpreterTester::NewObject( |
1273 "new (function Obj() { this.func = function() { return 0x265; }})()"); | 1266 "new (function Obj() { this.func = function() { return 0x265; }})()"); |
1274 Handle<Object> return_val = callable(object).ToHandleChecked(); | 1267 Handle<Object> return_val = callable(object).ToHandleChecked(); |
1275 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(0x265)); | 1268 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(0x265)); |
1276 } | 1269 } |
1277 | 1270 |
1278 // Check that receiver is passed properly. | 1271 // Check that receiver is passed properly. |
1279 { | 1272 { |
1280 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 1); | 1273 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 1); |
1281 Register reg = builder.register_allocator()->NewRegister(); | 1274 Register reg = builder.register_allocator()->NewRegister(); |
1282 RegisterList args = builder.register_allocator()->NewRegisterList(1); | 1275 RegisterList args = builder.register_allocator()->NewRegisterList(1); |
1283 builder.LoadNamedProperty(builder.Parameter(0), name, slot_index) | 1276 builder.LoadNamedProperty(builder.Parameter(0), name, slot_index) |
1284 .StoreAccumulatorInRegister(reg) | 1277 .StoreAccumulatorInRegister(reg) |
1285 .MoveRegister(builder.Parameter(0), args[0]); | 1278 .MoveRegister(builder.Parameter(0), args[0]); |
1286 builder.Call(reg, args, call_slot_index, Call::GLOBAL_CALL, tail_call_mode); | 1279 builder.Call(reg, args, call_slot_index, Call::GLOBAL_CALL, tail_call_mode); |
1287 builder.Return(); | 1280 builder.Return(); |
1288 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 1281 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
1289 | 1282 |
1290 InterpreterTester tester(isolate, bytecode_array, vector); | 1283 InterpreterTester tester(isolate, bytecode_array, metadata); |
1291 auto callable = tester.GetCallable<Handle<Object>>(); | 1284 auto callable = tester.GetCallable<Handle<Object>>(); |
1292 | 1285 |
1293 Handle<Object> object = InterpreterTester::NewObject( | 1286 Handle<Object> object = InterpreterTester::NewObject( |
1294 "new (function Obj() {" | 1287 "new (function Obj() {" |
1295 " this.val = 1234;" | 1288 " this.val = 1234;" |
1296 " this.func = function() { return this.val; };" | 1289 " this.func = function() { return this.val; };" |
1297 "})()"); | 1290 "})()"); |
1298 Handle<Object> return_val = callable(object).ToHandleChecked(); | 1291 Handle<Object> return_val = callable(object).ToHandleChecked(); |
1299 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(1234)); | 1292 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(1234)); |
1300 } | 1293 } |
(...skipping 12 matching lines...) Expand all Loading... |
1313 .StoreAccumulatorInRegister(args[1]) | 1306 .StoreAccumulatorInRegister(args[1]) |
1314 .LoadLiteral(Smi::FromInt(11)) | 1307 .LoadLiteral(Smi::FromInt(11)) |
1315 .StoreAccumulatorInRegister(args[2]); | 1308 .StoreAccumulatorInRegister(args[2]); |
1316 | 1309 |
1317 builder.Call(reg, args, call_slot_index, Call::GLOBAL_CALL, tail_call_mode); | 1310 builder.Call(reg, args, call_slot_index, Call::GLOBAL_CALL, tail_call_mode); |
1318 | 1311 |
1319 builder.Return(); | 1312 builder.Return(); |
1320 | 1313 |
1321 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 1314 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
1322 | 1315 |
1323 InterpreterTester tester(isolate, bytecode_array, vector); | 1316 InterpreterTester tester(isolate, bytecode_array, metadata); |
1324 auto callable = tester.GetCallable<Handle<Object>>(); | 1317 auto callable = tester.GetCallable<Handle<Object>>(); |
1325 | 1318 |
1326 Handle<Object> object = InterpreterTester::NewObject( | 1319 Handle<Object> object = InterpreterTester::NewObject( |
1327 "new (function Obj() { " | 1320 "new (function Obj() { " |
1328 " this.func = function(a, b) { return a - b; }" | 1321 " this.func = function(a, b) { return a - b; }" |
1329 "})()"); | 1322 "})()"); |
1330 Handle<Object> return_val = callable(object).ToHandleChecked(); | 1323 Handle<Object> return_val = callable(object).ToHandleChecked(); |
1331 CHECK(return_val->SameValue(Smi::FromInt(40))); | 1324 CHECK(return_val->SameValue(Smi::FromInt(40))); |
1332 } | 1325 } |
1333 | 1326 |
(...skipping 27 matching lines...) Expand all Loading... |
1361 .StoreAccumulatorInRegister(args[9]) | 1354 .StoreAccumulatorInRegister(args[9]) |
1362 .LoadLiteral(factory->NewStringFromAsciiChecked("j")) | 1355 .LoadLiteral(factory->NewStringFromAsciiChecked("j")) |
1363 .StoreAccumulatorInRegister(args[10]); | 1356 .StoreAccumulatorInRegister(args[10]); |
1364 | 1357 |
1365 builder.Call(reg, args, call_slot_index, Call::GLOBAL_CALL, tail_call_mode); | 1358 builder.Call(reg, args, call_slot_index, Call::GLOBAL_CALL, tail_call_mode); |
1366 | 1359 |
1367 builder.Return(); | 1360 builder.Return(); |
1368 | 1361 |
1369 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 1362 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
1370 | 1363 |
1371 InterpreterTester tester(isolate, bytecode_array, vector); | 1364 InterpreterTester tester(isolate, bytecode_array, metadata); |
1372 auto callable = tester.GetCallable<Handle<Object>>(); | 1365 auto callable = tester.GetCallable<Handle<Object>>(); |
1373 | 1366 |
1374 Handle<Object> object = InterpreterTester::NewObject( | 1367 Handle<Object> object = InterpreterTester::NewObject( |
1375 "new (function Obj() { " | 1368 "new (function Obj() { " |
1376 " this.prefix = \"prefix_\";" | 1369 " this.prefix = \"prefix_\";" |
1377 " this.func = function(a, b, c, d, e, f, g, h, i, j) {" | 1370 " this.func = function(a, b, c, d, e, f, g, h, i, j) {" |
1378 " return this.prefix + a + b + c + d + e + f + g + h + i + j;" | 1371 " return this.prefix + a + b + c + d + e + f + g + h + i + j;" |
1379 " }" | 1372 " }" |
1380 "})()"); | 1373 "})()"); |
1381 Handle<Object> return_val = callable(object).ToHandleChecked(); | 1374 Handle<Object> return_val = callable(object).ToHandleChecked(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1414 HandleAndZoneScope handles; | 1407 HandleAndZoneScope handles; |
1415 Isolate* isolate = handles.main_isolate(); | 1408 Isolate* isolate = handles.main_isolate(); |
1416 Zone zone(isolate->allocator(), ZONE_NAME); | 1409 Zone zone(isolate->allocator(), ZONE_NAME); |
1417 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 0, 0, 2); | 1410 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 0, 0, 2); |
1418 | 1411 |
1419 FeedbackVectorSpec feedback_spec(&zone); | 1412 FeedbackVectorSpec feedback_spec(&zone); |
1420 FeedbackVectorSlot slot = feedback_spec.AddInterpreterBinaryOpICSlot(); | 1413 FeedbackVectorSlot slot = feedback_spec.AddInterpreterBinaryOpICSlot(); |
1421 FeedbackVectorSlot slot1 = feedback_spec.AddInterpreterBinaryOpICSlot(); | 1414 FeedbackVectorSlot slot1 = feedback_spec.AddInterpreterBinaryOpICSlot(); |
1422 FeedbackVectorSlot slot2 = feedback_spec.AddInterpreterBinaryOpICSlot(); | 1415 FeedbackVectorSlot slot2 = feedback_spec.AddInterpreterBinaryOpICSlot(); |
1423 | 1416 |
1424 Handle<i::TypeFeedbackVector> vector = | 1417 Handle<i::TypeFeedbackMetadata> metadata = |
1425 NewTypeFeedbackVector(isolate, &feedback_spec); | 1418 NewTypeFeedbackMetadata(isolate, &feedback_spec); |
1426 | 1419 |
1427 Register reg(0), scratch(1); | 1420 Register reg(0), scratch(1); |
1428 BytecodeLabel label[3]; | 1421 BytecodeLabel label[3]; |
1429 | 1422 |
1430 builder.LoadLiteral(Smi::kZero) | 1423 builder.LoadLiteral(Smi::kZero) |
1431 .StoreAccumulatorInRegister(reg) | 1424 .StoreAccumulatorInRegister(reg) |
1432 .Jump(&label[1]); | 1425 .Jump(&label[1]); |
1433 SetRegister(builder, reg, 1024, scratch).Bind(&label[0]); | 1426 SetRegister(builder, reg, 1024, scratch).Bind(&label[0]); |
1434 IncrementRegister(builder, reg, 1, scratch, vector->GetIndex(slot)) | 1427 IncrementRegister(builder, reg, 1, scratch, GetIndex(slot)).Jump(&label[2]); |
1435 .Jump(&label[2]); | |
1436 SetRegister(builder, reg, 2048, scratch).Bind(&label[1]); | 1428 SetRegister(builder, reg, 2048, scratch).Bind(&label[1]); |
1437 IncrementRegister(builder, reg, 2, scratch, vector->GetIndex(slot1)) | 1429 IncrementRegister(builder, reg, 2, scratch, GetIndex(slot1)) |
1438 .JumpLoop(&label[0], 0); | 1430 .JumpLoop(&label[0], 0); |
1439 SetRegister(builder, reg, 4096, scratch).Bind(&label[2]); | 1431 SetRegister(builder, reg, 4096, scratch).Bind(&label[2]); |
1440 IncrementRegister(builder, reg, 4, scratch, vector->GetIndex(slot2)) | 1432 IncrementRegister(builder, reg, 4, scratch, GetIndex(slot2)) |
1441 .LoadAccumulatorWithRegister(reg) | 1433 .LoadAccumulatorWithRegister(reg) |
1442 .Return(); | 1434 .Return(); |
1443 | 1435 |
1444 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 1436 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
1445 InterpreterTester tester(isolate, bytecode_array, vector); | 1437 InterpreterTester tester(isolate, bytecode_array, metadata); |
1446 auto callable = tester.GetCallable<>(); | 1438 auto callable = tester.GetCallable<>(); |
1447 Handle<Object> return_value = callable().ToHandleChecked(); | 1439 Handle<Object> return_value = callable().ToHandleChecked(); |
1448 CHECK_EQ(Smi::cast(*return_value)->value(), 7); | 1440 CHECK_EQ(Smi::cast(*return_value)->value(), 7); |
1449 } | 1441 } |
1450 | 1442 |
1451 | 1443 |
1452 TEST(InterpreterConditionalJumps) { | 1444 TEST(InterpreterConditionalJumps) { |
1453 HandleAndZoneScope handles; | 1445 HandleAndZoneScope handles; |
1454 Isolate* isolate = handles.main_isolate(); | 1446 Isolate* isolate = handles.main_isolate(); |
1455 Zone zone(isolate->allocator(), ZONE_NAME); | 1447 Zone zone(isolate->allocator(), ZONE_NAME); |
1456 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 0, 0, 2); | 1448 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 0, 0, 2); |
1457 | 1449 |
1458 FeedbackVectorSpec feedback_spec(&zone); | 1450 FeedbackVectorSpec feedback_spec(&zone); |
1459 FeedbackVectorSlot slot = feedback_spec.AddInterpreterBinaryOpICSlot(); | 1451 FeedbackVectorSlot slot = feedback_spec.AddInterpreterBinaryOpICSlot(); |
1460 FeedbackVectorSlot slot1 = feedback_spec.AddInterpreterBinaryOpICSlot(); | 1452 FeedbackVectorSlot slot1 = feedback_spec.AddInterpreterBinaryOpICSlot(); |
1461 FeedbackVectorSlot slot2 = feedback_spec.AddInterpreterBinaryOpICSlot(); | 1453 FeedbackVectorSlot slot2 = feedback_spec.AddInterpreterBinaryOpICSlot(); |
1462 FeedbackVectorSlot slot3 = feedback_spec.AddInterpreterBinaryOpICSlot(); | 1454 FeedbackVectorSlot slot3 = feedback_spec.AddInterpreterBinaryOpICSlot(); |
1463 FeedbackVectorSlot slot4 = feedback_spec.AddInterpreterBinaryOpICSlot(); | 1455 FeedbackVectorSlot slot4 = feedback_spec.AddInterpreterBinaryOpICSlot(); |
1464 | 1456 |
1465 Handle<i::TypeFeedbackVector> vector = | 1457 Handle<i::TypeFeedbackMetadata> metadata = |
1466 NewTypeFeedbackVector(isolate, &feedback_spec); | 1458 NewTypeFeedbackMetadata(isolate, &feedback_spec); |
1467 | 1459 |
1468 Register reg(0), scratch(1); | 1460 Register reg(0), scratch(1); |
1469 BytecodeLabel label[2]; | 1461 BytecodeLabel label[2]; |
1470 BytecodeLabel done, done1; | 1462 BytecodeLabel done, done1; |
1471 | 1463 |
1472 builder.LoadLiteral(Smi::kZero) | 1464 builder.LoadLiteral(Smi::kZero) |
1473 .StoreAccumulatorInRegister(reg) | 1465 .StoreAccumulatorInRegister(reg) |
1474 .LoadFalse() | 1466 .LoadFalse() |
1475 .JumpIfFalse(&label[0]); | 1467 .JumpIfFalse(&label[0]); |
1476 IncrementRegister(builder, reg, 1024, scratch, vector->GetIndex(slot)) | 1468 IncrementRegister(builder, reg, 1024, scratch, GetIndex(slot)) |
1477 .Bind(&label[0]) | 1469 .Bind(&label[0]) |
1478 .LoadTrue() | 1470 .LoadTrue() |
1479 .JumpIfFalse(&done); | 1471 .JumpIfFalse(&done); |
1480 IncrementRegister(builder, reg, 1, scratch, vector->GetIndex(slot1)) | 1472 IncrementRegister(builder, reg, 1, scratch, GetIndex(slot1)) |
1481 .LoadTrue() | 1473 .LoadTrue() |
1482 .JumpIfTrue(&label[1]); | 1474 .JumpIfTrue(&label[1]); |
1483 IncrementRegister(builder, reg, 2048, scratch, vector->GetIndex(slot2)) | 1475 IncrementRegister(builder, reg, 2048, scratch, GetIndex(slot2)) |
1484 .Bind(&label[1]); | 1476 .Bind(&label[1]); |
1485 IncrementRegister(builder, reg, 2, scratch, vector->GetIndex(slot3)) | 1477 IncrementRegister(builder, reg, 2, scratch, GetIndex(slot3)) |
1486 .LoadFalse() | 1478 .LoadFalse() |
1487 .JumpIfTrue(&done1); | 1479 .JumpIfTrue(&done1); |
1488 IncrementRegister(builder, reg, 4, scratch, vector->GetIndex(slot4)) | 1480 IncrementRegister(builder, reg, 4, scratch, GetIndex(slot4)) |
1489 .LoadAccumulatorWithRegister(reg) | 1481 .LoadAccumulatorWithRegister(reg) |
1490 .Bind(&done) | 1482 .Bind(&done) |
1491 .Bind(&done1) | 1483 .Bind(&done1) |
1492 .Return(); | 1484 .Return(); |
1493 | 1485 |
1494 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 1486 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
1495 InterpreterTester tester(isolate, bytecode_array, vector); | 1487 InterpreterTester tester(isolate, bytecode_array, metadata); |
1496 auto callable = tester.GetCallable<>(); | 1488 auto callable = tester.GetCallable<>(); |
1497 Handle<Object> return_value = callable().ToHandleChecked(); | 1489 Handle<Object> return_value = callable().ToHandleChecked(); |
1498 CHECK_EQ(Smi::cast(*return_value)->value(), 7); | 1490 CHECK_EQ(Smi::cast(*return_value)->value(), 7); |
1499 } | 1491 } |
1500 | 1492 |
1501 TEST(InterpreterConditionalJumps2) { | 1493 TEST(InterpreterConditionalJumps2) { |
1502 // TODO(oth): Add tests for all conditional jumps near and far. | 1494 // TODO(oth): Add tests for all conditional jumps near and far. |
1503 HandleAndZoneScope handles; | 1495 HandleAndZoneScope handles; |
1504 Isolate* isolate = handles.main_isolate(); | 1496 Isolate* isolate = handles.main_isolate(); |
1505 Zone zone(isolate->allocator(), ZONE_NAME); | 1497 Zone zone(isolate->allocator(), ZONE_NAME); |
1506 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 0, 0, 2); | 1498 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 0, 0, 2); |
1507 | 1499 |
1508 FeedbackVectorSpec feedback_spec(&zone); | 1500 FeedbackVectorSpec feedback_spec(&zone); |
1509 FeedbackVectorSlot slot = feedback_spec.AddInterpreterBinaryOpICSlot(); | 1501 FeedbackVectorSlot slot = feedback_spec.AddInterpreterBinaryOpICSlot(); |
1510 FeedbackVectorSlot slot1 = feedback_spec.AddInterpreterBinaryOpICSlot(); | 1502 FeedbackVectorSlot slot1 = feedback_spec.AddInterpreterBinaryOpICSlot(); |
1511 FeedbackVectorSlot slot2 = feedback_spec.AddInterpreterBinaryOpICSlot(); | 1503 FeedbackVectorSlot slot2 = feedback_spec.AddInterpreterBinaryOpICSlot(); |
1512 FeedbackVectorSlot slot3 = feedback_spec.AddInterpreterBinaryOpICSlot(); | 1504 FeedbackVectorSlot slot3 = feedback_spec.AddInterpreterBinaryOpICSlot(); |
1513 FeedbackVectorSlot slot4 = feedback_spec.AddInterpreterBinaryOpICSlot(); | 1505 FeedbackVectorSlot slot4 = feedback_spec.AddInterpreterBinaryOpICSlot(); |
1514 | 1506 |
1515 Handle<i::TypeFeedbackVector> vector = | 1507 Handle<i::TypeFeedbackMetadata> metadata = |
1516 NewTypeFeedbackVector(isolate, &feedback_spec); | 1508 NewTypeFeedbackMetadata(isolate, &feedback_spec); |
1517 | 1509 |
1518 Register reg(0), scratch(1); | 1510 Register reg(0), scratch(1); |
1519 BytecodeLabel label[2]; | 1511 BytecodeLabel label[2]; |
1520 BytecodeLabel done, done1; | 1512 BytecodeLabel done, done1; |
1521 | 1513 |
1522 builder.LoadLiteral(Smi::kZero) | 1514 builder.LoadLiteral(Smi::kZero) |
1523 .StoreAccumulatorInRegister(reg) | 1515 .StoreAccumulatorInRegister(reg) |
1524 .LoadFalse() | 1516 .LoadFalse() |
1525 .JumpIfFalse(&label[0]); | 1517 .JumpIfFalse(&label[0]); |
1526 IncrementRegister(builder, reg, 1024, scratch, vector->GetIndex(slot)) | 1518 IncrementRegister(builder, reg, 1024, scratch, GetIndex(slot)) |
1527 .Bind(&label[0]) | 1519 .Bind(&label[0]) |
1528 .LoadTrue() | 1520 .LoadTrue() |
1529 .JumpIfFalse(&done); | 1521 .JumpIfFalse(&done); |
1530 IncrementRegister(builder, reg, 1, scratch, vector->GetIndex(slot1)) | 1522 IncrementRegister(builder, reg, 1, scratch, GetIndex(slot1)) |
1531 .LoadTrue() | 1523 .LoadTrue() |
1532 .JumpIfTrue(&label[1]); | 1524 .JumpIfTrue(&label[1]); |
1533 IncrementRegister(builder, reg, 2048, scratch, vector->GetIndex(slot2)) | 1525 IncrementRegister(builder, reg, 2048, scratch, GetIndex(slot2)) |
1534 .Bind(&label[1]); | 1526 .Bind(&label[1]); |
1535 IncrementRegister(builder, reg, 2, scratch, vector->GetIndex(slot3)) | 1527 IncrementRegister(builder, reg, 2, scratch, GetIndex(slot3)) |
1536 .LoadFalse() | 1528 .LoadFalse() |
1537 .JumpIfTrue(&done1); | 1529 .JumpIfTrue(&done1); |
1538 IncrementRegister(builder, reg, 4, scratch, vector->GetIndex(slot4)) | 1530 IncrementRegister(builder, reg, 4, scratch, GetIndex(slot4)) |
1539 .LoadAccumulatorWithRegister(reg) | 1531 .LoadAccumulatorWithRegister(reg) |
1540 .Bind(&done) | 1532 .Bind(&done) |
1541 .Bind(&done1) | 1533 .Bind(&done1) |
1542 .Return(); | 1534 .Return(); |
1543 | 1535 |
1544 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 1536 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
1545 InterpreterTester tester(isolate, bytecode_array, vector); | 1537 InterpreterTester tester(isolate, bytecode_array, metadata); |
1546 auto callable = tester.GetCallable<>(); | 1538 auto callable = tester.GetCallable<>(); |
1547 Handle<Object> return_value = callable().ToHandleChecked(); | 1539 Handle<Object> return_value = callable().ToHandleChecked(); |
1548 CHECK_EQ(Smi::cast(*return_value)->value(), 7); | 1540 CHECK_EQ(Smi::cast(*return_value)->value(), 7); |
1549 } | 1541 } |
1550 | 1542 |
1551 TEST(InterpreterJumpConstantWith16BitOperand) { | 1543 TEST(InterpreterJumpConstantWith16BitOperand) { |
1552 HandleAndZoneScope handles; | 1544 HandleAndZoneScope handles; |
1553 Isolate* isolate = handles.main_isolate(); | 1545 Isolate* isolate = handles.main_isolate(); |
1554 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 257); | 1546 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 257); |
1555 | 1547 |
1556 Zone zone(isolate->allocator(), ZONE_NAME); | 1548 Zone zone(isolate->allocator(), ZONE_NAME); |
1557 | 1549 |
1558 FeedbackVectorSpec feedback_spec(&zone); | 1550 FeedbackVectorSpec feedback_spec(&zone); |
1559 FeedbackVectorSlot slot = feedback_spec.AddInterpreterBinaryOpICSlot(); | 1551 FeedbackVectorSlot slot = feedback_spec.AddInterpreterBinaryOpICSlot(); |
1560 Handle<i::TypeFeedbackVector> vector = | 1552 Handle<i::TypeFeedbackMetadata> metadata = |
1561 NewTypeFeedbackVector(isolate, &feedback_spec); | 1553 NewTypeFeedbackMetadata(isolate, &feedback_spec); |
1562 | 1554 |
1563 Register reg(0), scratch(256); | 1555 Register reg(0), scratch(256); |
1564 BytecodeLabel done, fake; | 1556 BytecodeLabel done, fake; |
1565 | 1557 |
1566 builder.LoadLiteral(Smi::kZero); | 1558 builder.LoadLiteral(Smi::kZero); |
1567 builder.StoreAccumulatorInRegister(reg); | 1559 builder.StoreAccumulatorInRegister(reg); |
1568 // Consume all 8-bit operands | 1560 // Consume all 8-bit operands |
1569 for (int i = 1; i <= 256; i++) { | 1561 for (int i = 1; i <= 256; i++) { |
1570 builder.LoadLiteral(isolate->factory()->NewNumber(i)); | 1562 builder.LoadLiteral(isolate->factory()->NewNumber(i)); |
1571 builder.BinaryOperation(Token::Value::ADD, reg, vector->GetIndex(slot)); | 1563 builder.BinaryOperation(Token::Value::ADD, reg, GetIndex(slot)); |
1572 builder.StoreAccumulatorInRegister(reg); | 1564 builder.StoreAccumulatorInRegister(reg); |
1573 } | 1565 } |
1574 builder.Jump(&done); | 1566 builder.Jump(&done); |
1575 | 1567 |
1576 // Emit more than 16-bit immediate operands worth of code to jump over. | 1568 // Emit more than 16-bit immediate operands worth of code to jump over. |
1577 builder.Bind(&fake); | 1569 builder.Bind(&fake); |
1578 for (int i = 0; i < 6600; i++) { | 1570 for (int i = 0; i < 6600; i++) { |
1579 builder.LoadLiteral(Smi::kZero); // 1-byte | 1571 builder.LoadLiteral(Smi::kZero); // 1-byte |
1580 builder.BinaryOperation(Token::Value::ADD, scratch, | 1572 builder.BinaryOperation(Token::Value::ADD, scratch, |
1581 vector->GetIndex(slot)); // 6-bytes | 1573 GetIndex(slot)); // 6-bytes |
1582 builder.StoreAccumulatorInRegister(scratch); // 4-bytes | 1574 builder.StoreAccumulatorInRegister(scratch); // 4-bytes |
1583 builder.MoveRegister(scratch, reg); // 6-bytes | 1575 builder.MoveRegister(scratch, reg); // 6-bytes |
1584 } | 1576 } |
1585 builder.Bind(&done); | 1577 builder.Bind(&done); |
1586 builder.LoadAccumulatorWithRegister(reg); | 1578 builder.LoadAccumulatorWithRegister(reg); |
1587 builder.Return(); | 1579 builder.Return(); |
1588 | 1580 |
1589 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 1581 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
1590 BytecodeArrayIterator iterator(bytecode_array); | 1582 BytecodeArrayIterator iterator(bytecode_array); |
1591 | 1583 |
1592 bool found_16bit_constant_jump = false; | 1584 bool found_16bit_constant_jump = false; |
1593 while (!iterator.done()) { | 1585 while (!iterator.done()) { |
1594 if (iterator.current_bytecode() == Bytecode::kJumpConstant && | 1586 if (iterator.current_bytecode() == Bytecode::kJumpConstant && |
1595 iterator.current_operand_scale() == OperandScale::kDouble) { | 1587 iterator.current_operand_scale() == OperandScale::kDouble) { |
1596 found_16bit_constant_jump = true; | 1588 found_16bit_constant_jump = true; |
1597 break; | 1589 break; |
1598 } | 1590 } |
1599 iterator.Advance(); | 1591 iterator.Advance(); |
1600 } | 1592 } |
1601 CHECK(found_16bit_constant_jump); | 1593 CHECK(found_16bit_constant_jump); |
1602 | 1594 |
1603 InterpreterTester tester(isolate, bytecode_array, vector); | 1595 InterpreterTester tester(isolate, bytecode_array, metadata); |
1604 auto callable = tester.GetCallable<>(); | 1596 auto callable = tester.GetCallable<>(); |
1605 Handle<Object> return_value = callable().ToHandleChecked(); | 1597 Handle<Object> return_value = callable().ToHandleChecked(); |
1606 CHECK_EQ(Smi::cast(*return_value)->value(), 256.0 / 2 * (1 + 256)); | 1598 CHECK_EQ(Smi::cast(*return_value)->value(), 256.0 / 2 * (1 + 256)); |
1607 } | 1599 } |
1608 | 1600 |
1609 TEST(InterpreterJumpWith32BitOperand) { | 1601 TEST(InterpreterJumpWith32BitOperand) { |
1610 HandleAndZoneScope handles; | 1602 HandleAndZoneScope handles; |
1611 Isolate* isolate = handles.main_isolate(); | 1603 Isolate* isolate = handles.main_isolate(); |
1612 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 1); | 1604 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 1, 0, 1); |
1613 Register reg(0); | 1605 Register reg(0); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1696 Token::Value comparison = kComparisonTypes[c]; | 1688 Token::Value comparison = kComparisonTypes[c]; |
1697 for (size_t i = 0; i < arraysize(inputs); i++) { | 1689 for (size_t i = 0; i < arraysize(inputs); i++) { |
1698 for (size_t j = 0; j < arraysize(inputs); j++) { | 1690 for (size_t j = 0; j < arraysize(inputs); j++) { |
1699 HandleAndZoneScope handles; | 1691 HandleAndZoneScope handles; |
1700 Isolate* isolate = handles.main_isolate(); | 1692 Isolate* isolate = handles.main_isolate(); |
1701 Zone zone(isolate->allocator(), ZONE_NAME); | 1693 Zone zone(isolate->allocator(), ZONE_NAME); |
1702 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 0, 0, 1); | 1694 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 0, 0, 1); |
1703 | 1695 |
1704 FeedbackVectorSpec feedback_spec(&zone); | 1696 FeedbackVectorSpec feedback_spec(&zone); |
1705 FeedbackVectorSlot slot = feedback_spec.AddInterpreterCompareICSlot(); | 1697 FeedbackVectorSlot slot = feedback_spec.AddInterpreterCompareICSlot(); |
1706 Handle<i::TypeFeedbackVector> vector = | 1698 Handle<i::TypeFeedbackMetadata> metadata = |
1707 NewTypeFeedbackVector(isolate, &feedback_spec); | 1699 NewTypeFeedbackMetadata(isolate, &feedback_spec); |
1708 | 1700 |
1709 Register r0(0); | 1701 Register r0(0); |
1710 builder.LoadLiteral(Smi::FromInt(inputs[i])) | 1702 builder.LoadLiteral(Smi::FromInt(inputs[i])) |
1711 .StoreAccumulatorInRegister(r0) | 1703 .StoreAccumulatorInRegister(r0) |
1712 .LoadLiteral(Smi::FromInt(inputs[j])) | 1704 .LoadLiteral(Smi::FromInt(inputs[j])) |
1713 .CompareOperation(comparison, r0, vector->GetIndex(slot)) | 1705 .CompareOperation(comparison, r0, GetIndex(slot)) |
1714 .Return(); | 1706 .Return(); |
1715 | 1707 |
1716 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 1708 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
1717 InterpreterTester tester(isolate, bytecode_array, vector); | 1709 InterpreterTester tester(isolate, bytecode_array, metadata); |
1718 auto callable = tester.GetCallable<>(); | 1710 auto callable = tester.GetCallable<>(); |
1719 Handle<Object> return_value = callable().ToHandleChecked(); | 1711 Handle<Object> return_value = callable().ToHandleChecked(); |
1720 CHECK(return_value->IsBoolean()); | 1712 CHECK(return_value->IsBoolean()); |
1721 CHECK_EQ(return_value->BooleanValue(), | 1713 CHECK_EQ(return_value->BooleanValue(), |
1722 CompareC(comparison, inputs[i], inputs[j])); | 1714 CompareC(comparison, inputs[i], inputs[j])); |
1723 Object* feedback = vector->Get(slot); | 1715 Object* feedback = callable.vector()->Get(slot); |
1724 CHECK(feedback->IsSmi()); | 1716 CHECK(feedback->IsSmi()); |
1725 CHECK_EQ(CompareOperationFeedback::kSignedSmall, | 1717 CHECK_EQ(CompareOperationFeedback::kSignedSmall, |
1726 static_cast<Smi*>(feedback)->value()); | 1718 static_cast<Smi*>(feedback)->value()); |
1727 } | 1719 } |
1728 } | 1720 } |
1729 } | 1721 } |
1730 } | 1722 } |
1731 | 1723 |
1732 | 1724 |
1733 TEST(InterpreterHeapNumberComparisons) { | 1725 TEST(InterpreterHeapNumberComparisons) { |
1734 double inputs[] = {std::numeric_limits<double>::min(), | 1726 double inputs[] = {std::numeric_limits<double>::min(), |
1735 std::numeric_limits<double>::max(), | 1727 std::numeric_limits<double>::max(), |
1736 -0.001, | 1728 -0.001, |
1737 0.01, | 1729 0.01, |
1738 0.1000001, | 1730 0.1000001, |
1739 1e99, | 1731 1e99, |
1740 -1e-99}; | 1732 -1e-99}; |
1741 for (size_t c = 0; c < arraysize(kComparisonTypes); c++) { | 1733 for (size_t c = 0; c < arraysize(kComparisonTypes); c++) { |
1742 Token::Value comparison = kComparisonTypes[c]; | 1734 Token::Value comparison = kComparisonTypes[c]; |
1743 for (size_t i = 0; i < arraysize(inputs); i++) { | 1735 for (size_t i = 0; i < arraysize(inputs); i++) { |
1744 for (size_t j = 0; j < arraysize(inputs); j++) { | 1736 for (size_t j = 0; j < arraysize(inputs); j++) { |
1745 HandleAndZoneScope handles; | 1737 HandleAndZoneScope handles; |
1746 Isolate* isolate = handles.main_isolate(); | 1738 Isolate* isolate = handles.main_isolate(); |
1747 Factory* factory = isolate->factory(); | 1739 Factory* factory = isolate->factory(); |
1748 Zone zone(isolate->allocator(), ZONE_NAME); | 1740 Zone zone(isolate->allocator(), ZONE_NAME); |
1749 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 0, 0, 1); | 1741 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 0, 0, 1); |
1750 | 1742 |
1751 FeedbackVectorSpec feedback_spec(&zone); | 1743 FeedbackVectorSpec feedback_spec(&zone); |
1752 FeedbackVectorSlot slot = feedback_spec.AddInterpreterCompareICSlot(); | 1744 FeedbackVectorSlot slot = feedback_spec.AddInterpreterCompareICSlot(); |
1753 Handle<i::TypeFeedbackVector> vector = | 1745 Handle<i::TypeFeedbackMetadata> metadata = |
1754 NewTypeFeedbackVector(isolate, &feedback_spec); | 1746 NewTypeFeedbackMetadata(isolate, &feedback_spec); |
1755 | 1747 |
1756 Register r0(0); | 1748 Register r0(0); |
1757 builder.LoadLiteral(factory->NewHeapNumber(inputs[i])) | 1749 builder.LoadLiteral(factory->NewHeapNumber(inputs[i])) |
1758 .StoreAccumulatorInRegister(r0) | 1750 .StoreAccumulatorInRegister(r0) |
1759 .LoadLiteral(factory->NewHeapNumber(inputs[j])) | 1751 .LoadLiteral(factory->NewHeapNumber(inputs[j])) |
1760 .CompareOperation(comparison, r0, vector->GetIndex(slot)) | 1752 .CompareOperation(comparison, r0, GetIndex(slot)) |
1761 .Return(); | 1753 .Return(); |
1762 | 1754 |
1763 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 1755 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
1764 InterpreterTester tester(isolate, bytecode_array, vector); | 1756 InterpreterTester tester(isolate, bytecode_array, metadata); |
1765 auto callable = tester.GetCallable<>(); | 1757 auto callable = tester.GetCallable<>(); |
1766 Handle<Object> return_value = callable().ToHandleChecked(); | 1758 Handle<Object> return_value = callable().ToHandleChecked(); |
1767 CHECK(return_value->IsBoolean()); | 1759 CHECK(return_value->IsBoolean()); |
1768 CHECK_EQ(return_value->BooleanValue(), | 1760 CHECK_EQ(return_value->BooleanValue(), |
1769 CompareC(comparison, inputs[i], inputs[j])); | 1761 CompareC(comparison, inputs[i], inputs[j])); |
1770 Object* feedback = vector->Get(slot); | 1762 Object* feedback = callable.vector()->Get(slot); |
1771 CHECK(feedback->IsSmi()); | 1763 CHECK(feedback->IsSmi()); |
1772 CHECK_EQ(CompareOperationFeedback::kNumber, | 1764 CHECK_EQ(CompareOperationFeedback::kNumber, |
1773 static_cast<Smi*>(feedback)->value()); | 1765 static_cast<Smi*>(feedback)->value()); |
1774 } | 1766 } |
1775 } | 1767 } |
1776 } | 1768 } |
1777 } | 1769 } |
1778 | 1770 |
1779 | 1771 |
1780 TEST(InterpreterStringComparisons) { | 1772 TEST(InterpreterStringComparisons) { |
1781 HandleAndZoneScope handles; | 1773 HandleAndZoneScope handles; |
1782 Isolate* isolate = handles.main_isolate(); | 1774 Isolate* isolate = handles.main_isolate(); |
1783 Factory* factory = isolate->factory(); | 1775 Factory* factory = isolate->factory(); |
1784 Zone zone(isolate->allocator(), ZONE_NAME); | 1776 Zone zone(isolate->allocator(), ZONE_NAME); |
1785 | 1777 |
1786 std::string inputs[] = {"A", "abc", "z", "", "Foo!", "Foo"}; | 1778 std::string inputs[] = {"A", "abc", "z", "", "Foo!", "Foo"}; |
1787 | 1779 |
1788 for (size_t c = 0; c < arraysize(kComparisonTypes); c++) { | 1780 for (size_t c = 0; c < arraysize(kComparisonTypes); c++) { |
1789 Token::Value comparison = kComparisonTypes[c]; | 1781 Token::Value comparison = kComparisonTypes[c]; |
1790 for (size_t i = 0; i < arraysize(inputs); i++) { | 1782 for (size_t i = 0; i < arraysize(inputs); i++) { |
1791 for (size_t j = 0; j < arraysize(inputs); j++) { | 1783 for (size_t j = 0; j < arraysize(inputs); j++) { |
1792 CanonicalHandleScope canonical(isolate); | 1784 CanonicalHandleScope canonical(isolate); |
1793 const char* lhs = inputs[i].c_str(); | 1785 const char* lhs = inputs[i].c_str(); |
1794 const char* rhs = inputs[j].c_str(); | 1786 const char* rhs = inputs[j].c_str(); |
1795 | 1787 |
1796 FeedbackVectorSpec feedback_spec(&zone); | 1788 FeedbackVectorSpec feedback_spec(&zone); |
1797 FeedbackVectorSlot slot = feedback_spec.AddInterpreterCompareICSlot(); | 1789 FeedbackVectorSlot slot = feedback_spec.AddInterpreterCompareICSlot(); |
1798 Handle<i::TypeFeedbackVector> vector = | 1790 Handle<i::TypeFeedbackMetadata> metadata = |
1799 NewTypeFeedbackVector(isolate, &feedback_spec); | 1791 NewTypeFeedbackMetadata(isolate, &feedback_spec); |
1800 | 1792 |
1801 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 0, 0, 1); | 1793 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 0, 0, 1); |
1802 Register r0(0); | 1794 Register r0(0); |
1803 builder.LoadLiteral(factory->InternalizeUtf8String(lhs)) | 1795 builder.LoadLiteral(factory->InternalizeUtf8String(lhs)) |
1804 .StoreAccumulatorInRegister(r0) | 1796 .StoreAccumulatorInRegister(r0) |
1805 .LoadLiteral(factory->InternalizeUtf8String(rhs)) | 1797 .LoadLiteral(factory->InternalizeUtf8String(rhs)) |
1806 .CompareOperation(comparison, r0, vector->GetIndex(slot)) | 1798 .CompareOperation(comparison, r0, GetIndex(slot)) |
1807 .Return(); | 1799 .Return(); |
1808 | 1800 |
1809 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); | 1801 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); |
1810 InterpreterTester tester(isolate, bytecode_array, vector); | 1802 InterpreterTester tester(isolate, bytecode_array, metadata); |
1811 auto callable = tester.GetCallable<>(); | 1803 auto callable = tester.GetCallable<>(); |
1812 Handle<Object> return_value = callable().ToHandleChecked(); | 1804 Handle<Object> return_value = callable().ToHandleChecked(); |
1813 CHECK(return_value->IsBoolean()); | 1805 CHECK(return_value->IsBoolean()); |
1814 CHECK_EQ(return_value->BooleanValue(), | 1806 CHECK_EQ(return_value->BooleanValue(), |
1815 CompareC(comparison, inputs[i], inputs[j])); | 1807 CompareC(comparison, inputs[i], inputs[j])); |
1816 Object* feedback = vector->Get(slot); | 1808 Object* feedback = callable.vector()->Get(slot); |
1817 CHECK(feedback->IsSmi()); | 1809 CHECK(feedback->IsSmi()); |
1818 int const expected_feedback = | 1810 int const expected_feedback = |
1819 Token::IsOrderedRelationalCompareOp(comparison) | 1811 Token::IsOrderedRelationalCompareOp(comparison) |
1820 ? CompareOperationFeedback::kString | 1812 ? CompareOperationFeedback::kString |
1821 : CompareOperationFeedback::kInternalizedString; | 1813 : CompareOperationFeedback::kInternalizedString; |
1822 CHECK_EQ(expected_feedback, static_cast<Smi*>(feedback)->value()); | 1814 CHECK_EQ(expected_feedback, static_cast<Smi*>(feedback)->value()); |
1823 } | 1815 } |
1824 } | 1816 } |
1825 } | 1817 } |
1826 } | 1818 } |
(...skipping 20 matching lines...) Expand all Loading... |
1847 double rhs = StringToDouble(&unicode_cache, rhs_cstr, | 1839 double rhs = StringToDouble(&unicode_cache, rhs_cstr, |
1848 ConversionFlags::NO_FLAGS); | 1840 ConversionFlags::NO_FLAGS); |
1849 HandleAndZoneScope handles; | 1841 HandleAndZoneScope handles; |
1850 Isolate* isolate = handles.main_isolate(); | 1842 Isolate* isolate = handles.main_isolate(); |
1851 Factory* factory = isolate->factory(); | 1843 Factory* factory = isolate->factory(); |
1852 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 0, 0, 1); | 1844 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 0, 0, 1); |
1853 Zone zone(isolate->allocator(), ZONE_NAME); | 1845 Zone zone(isolate->allocator(), ZONE_NAME); |
1854 | 1846 |
1855 FeedbackVectorSpec feedback_spec(&zone); | 1847 FeedbackVectorSpec feedback_spec(&zone); |
1856 FeedbackVectorSlot slot = feedback_spec.AddInterpreterCompareICSlot(); | 1848 FeedbackVectorSlot slot = feedback_spec.AddInterpreterCompareICSlot(); |
1857 Handle<i::TypeFeedbackVector> vector = | 1849 Handle<i::TypeFeedbackMetadata> metadata = |
1858 NewTypeFeedbackVector(isolate, &feedback_spec); | 1850 NewTypeFeedbackMetadata(isolate, &feedback_spec); |
1859 | 1851 |
1860 Register r0(0); | 1852 Register r0(0); |
1861 if (pass == 0) { | 1853 if (pass == 0) { |
1862 // Comparison with HeapNumber on the lhs and String on the rhs | 1854 // Comparison with HeapNumber on the lhs and String on the rhs |
1863 builder.LoadLiteral(factory->NewNumber(lhs)) | 1855 builder.LoadLiteral(factory->NewNumber(lhs)) |
1864 .StoreAccumulatorInRegister(r0) | 1856 .StoreAccumulatorInRegister(r0) |
1865 .LoadLiteral(factory->NewStringFromAsciiChecked(rhs_cstr)) | 1857 .LoadLiteral(factory->NewStringFromAsciiChecked(rhs_cstr)) |
1866 .CompareOperation(comparison, r0, vector->GetIndex(slot)) | 1858 .CompareOperation(comparison, r0, GetIndex(slot)) |
1867 .Return(); | 1859 .Return(); |
1868 } else { | 1860 } else { |
1869 // Comparison with HeapNumber on the rhs and String on the lhs | 1861 // Comparison with HeapNumber on the rhs and String on the lhs |
1870 builder.LoadLiteral(factory->NewStringFromAsciiChecked(lhs_cstr)) | 1862 builder.LoadLiteral(factory->NewStringFromAsciiChecked(lhs_cstr)) |
1871 .StoreAccumulatorInRegister(r0) | 1863 .StoreAccumulatorInRegister(r0) |
1872 .LoadLiteral(factory->NewNumber(rhs)) | 1864 .LoadLiteral(factory->NewNumber(rhs)) |
1873 .CompareOperation(comparison, r0, vector->GetIndex(slot)) | 1865 .CompareOperation(comparison, r0, GetIndex(slot)) |
1874 .Return(); | 1866 .Return(); |
1875 } | 1867 } |
1876 | 1868 |
1877 Handle<BytecodeArray> bytecode_array = | 1869 Handle<BytecodeArray> bytecode_array = |
1878 builder.ToBytecodeArray(isolate); | 1870 builder.ToBytecodeArray(isolate); |
1879 InterpreterTester tester(isolate, bytecode_array, vector); | 1871 InterpreterTester tester(isolate, bytecode_array, metadata); |
1880 auto callable = tester.GetCallable<>(); | 1872 auto callable = tester.GetCallable<>(); |
1881 Handle<Object> return_value = callable().ToHandleChecked(); | 1873 Handle<Object> return_value = callable().ToHandleChecked(); |
1882 CHECK(return_value->IsBoolean()); | 1874 CHECK(return_value->IsBoolean()); |
1883 CHECK_EQ(return_value->BooleanValue(), | 1875 CHECK_EQ(return_value->BooleanValue(), |
1884 CompareC(comparison, lhs, rhs, true)); | 1876 CompareC(comparison, lhs, rhs, true)); |
1885 Object* feedback = vector->Get(slot); | 1877 Object* feedback = callable.vector()->Get(slot); |
1886 CHECK(feedback->IsSmi()); | 1878 CHECK(feedback->IsSmi()); |
1887 // kNumber | kString gets converted to CompareOperationHint::kAny. | 1879 // kNumber | kString gets converted to CompareOperationHint::kAny. |
1888 int expected_feedback = CompareOperationFeedback::kNumber | | 1880 int expected_feedback = CompareOperationFeedback::kNumber | |
1889 CompareOperationFeedback::kString; | 1881 CompareOperationFeedback::kString; |
1890 CHECK_EQ(expected_feedback, static_cast<Smi*>(feedback)->value()); | 1882 CHECK_EQ(expected_feedback, static_cast<Smi*>(feedback)->value()); |
1891 } | 1883 } |
1892 } | 1884 } |
1893 } | 1885 } |
1894 } | 1886 } |
1895 } | 1887 } |
(...skipping 2936 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4832 auto callable = tester.GetCallable<>(); | 4824 auto callable = tester.GetCallable<>(); |
4833 | 4825 |
4834 Handle<i::Object> return_value = callable().ToHandleChecked(); | 4826 Handle<i::Object> return_value = callable().ToHandleChecked(); |
4835 CHECK(return_value->SameValue(*tests[i].second)); | 4827 CHECK(return_value->SameValue(*tests[i].second)); |
4836 } | 4828 } |
4837 } | 4829 } |
4838 | 4830 |
4839 } // namespace interpreter | 4831 } // namespace interpreter |
4840 } // namespace internal | 4832 } // namespace internal |
4841 } // namespace v8 | 4833 } // namespace v8 |
OLD | NEW |