Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: test/cctest/interpreter/test-interpreter.cc

Issue 1309843007: [Interpreter] Add support for property load operations. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Remove templated FitsInOperand since std::is_integral is not supported on Mac Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/interpreter.h" 10 #include "src/interpreter/interpreter.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 } 46 }
47 47
48 private: 48 private:
49 Isolate* isolate_; 49 Isolate* isolate_;
50 Handle<JSFunction> function_; 50 Handle<JSFunction> function_;
51 }; 51 };
52 52
53 53
54 class InterpreterTester { 54 class InterpreterTester {
55 public: 55 public:
56 InterpreterTester(Isolate* isolate, Handle<BytecodeArray> bytecode) 56 InterpreterTester(Isolate* isolate, Handle<BytecodeArray> bytecode,
57 : isolate_(isolate), bytecode_(bytecode) { 57 MaybeHandle<TypeFeedbackVector> feedback_vector =
58 MaybeHandle<TypeFeedbackVector>())
59 : isolate_(isolate),
60 bytecode_(bytecode),
61 feedback_vector_(feedback_vector) {
58 i::FLAG_ignition = true; 62 i::FLAG_ignition = true;
59 // Ensure handler table is generated. 63 // Ensure handler table is generated.
60 isolate->interpreter()->Initialize(); 64 isolate->interpreter()->Initialize();
61 } 65 }
62 virtual ~InterpreterTester() {} 66 virtual ~InterpreterTester() {}
63 67
64 template <class... A> 68 template <class... A>
65 InterpreterCallable<A...> GetCallable() { 69 InterpreterCallable<A...> GetCallable() {
66 return InterpreterCallable<A...>(isolate_, GetBytecodeFunction<A...>()); 70 return InterpreterCallable<A...>(isolate_, GetBytecodeFunction<A...>());
67 } 71 }
68 72
73 Handle<Object> NewObject(const char* script) {
74 return v8::Utils::OpenHandle(*CompileRun(script));
75 }
76
69 private: 77 private:
70 Isolate* isolate_; 78 Isolate* isolate_;
71 Handle<BytecodeArray> bytecode_; 79 Handle<BytecodeArray> bytecode_;
80 MaybeHandle<TypeFeedbackVector> feedback_vector_;
72 81
73 template <class... A> 82 template <class... A>
74 Handle<JSFunction> GetBytecodeFunction() { 83 Handle<JSFunction> GetBytecodeFunction() {
75 int arg_count = sizeof...(A); 84 int arg_count = sizeof...(A);
76 std::string function_text("(function("); 85 std::string function_text("(function(");
77 for (int i = 0; i < arg_count; i++) { 86 for (int i = 0; i < arg_count; i++) {
78 function_text += i == 0 ? "a" : ", a"; 87 function_text += i == 0 ? "a" : ", a";
79 } 88 }
80 function_text += "){})"; 89 function_text += "){})";
81 90
82 Handle<JSFunction> function = v8::Utils::OpenHandle( 91 Handle<JSFunction> function = v8::Utils::OpenHandle(
83 *v8::Handle<v8::Function>::Cast(CompileRun(function_text.c_str()))); 92 *v8::Handle<v8::Function>::Cast(CompileRun(function_text.c_str())));
84 function->ReplaceCode(*isolate_->builtins()->InterpreterEntryTrampoline()); 93 function->ReplaceCode(*isolate_->builtins()->InterpreterEntryTrampoline());
85 function->shared()->set_function_data(*bytecode_); 94 function->shared()->set_function_data(*bytecode_);
95 if (!feedback_vector_.is_null()) {
96 function->shared()->set_feedback_vector(
97 *feedback_vector_.ToHandleChecked());
98 }
86 return function; 99 return function;
87 } 100 }
88 101
89 DISALLOW_COPY_AND_ASSIGN(InterpreterTester); 102 DISALLOW_COPY_AND_ASSIGN(InterpreterTester);
90 }; 103 };
91 104
92 } // namespace interpreter 105 } // namespace interpreter
93 } // namespace internal 106 } // namespace internal
94 } // namespace v8 107 } // namespace v8
95 108
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 InterpreterTester tester(handles.main_isolate(), bytecode_array); 406 InterpreterTester tester(handles.main_isolate(), bytecode_array);
394 auto callable = tester.GetCallable<>(); 407 auto callable = tester.GetCallable<>();
395 Handle<Object> return_val = callable().ToHandleChecked(); 408 Handle<Object> return_val = callable().ToHandleChecked();
396 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(21)); 409 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(21));
397 } 410 }
398 411
399 412
400 TEST(InterpreterParameter1) { 413 TEST(InterpreterParameter1) {
401 HandleAndZoneScope handles; 414 HandleAndZoneScope handles;
402 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone()); 415 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone());
403 builder.set_locals_count(1); 416 builder.set_locals_count(0);
404 builder.set_parameter_count(1); 417 builder.set_parameter_count(1);
405 builder.LoadAccumulatorWithRegister(builder.Parameter(0)).Return(); 418 builder.LoadAccumulatorWithRegister(builder.Parameter(0)).Return();
406 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); 419 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
407 420
408 InterpreterTester tester(handles.main_isolate(), bytecode_array); 421 InterpreterTester tester(handles.main_isolate(), bytecode_array);
409 auto callable = tester.GetCallable<Handle<Object>>(); 422 auto callable = tester.GetCallable<Handle<Object>>();
410 423
411 // Check for heap objects. 424 // Check for heap objects.
412 Handle<Object> true_value = handles.main_isolate()->factory()->true_value(); 425 Handle<Object> true_value = handles.main_isolate()->factory()->true_value();
413 Handle<Object> return_val = callable(true_value).ToHandleChecked(); 426 Handle<Object> return_val = callable(true_value).ToHandleChecked();
414 CHECK(return_val.is_identical_to(true_value)); 427 CHECK(return_val.is_identical_to(true_value));
415 428
416 // Check for Smis. 429 // Check for Smis.
417 return_val = callable(Handle<Smi>(Smi::FromInt(3), handles.main_isolate())) 430 return_val = callable(Handle<Smi>(Smi::FromInt(3), handles.main_isolate()))
418 .ToHandleChecked(); 431 .ToHandleChecked();
419 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(3)); 432 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(3));
420 } 433 }
421 434
422 435
423 TEST(InterpreterParameter8) { 436 TEST(InterpreterParameter8) {
424 HandleAndZoneScope handles; 437 HandleAndZoneScope handles;
425 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone()); 438 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone());
426 builder.set_locals_count(1); 439 builder.set_locals_count(0);
427 builder.set_parameter_count(8); 440 builder.set_parameter_count(8);
428 builder.LoadAccumulatorWithRegister(builder.Parameter(0)) 441 builder.LoadAccumulatorWithRegister(builder.Parameter(0))
429 .BinaryOperation(Token::Value::ADD, builder.Parameter(1)) 442 .BinaryOperation(Token::Value::ADD, builder.Parameter(1))
430 .BinaryOperation(Token::Value::ADD, builder.Parameter(2)) 443 .BinaryOperation(Token::Value::ADD, builder.Parameter(2))
431 .BinaryOperation(Token::Value::ADD, builder.Parameter(3)) 444 .BinaryOperation(Token::Value::ADD, builder.Parameter(3))
432 .BinaryOperation(Token::Value::ADD, builder.Parameter(4)) 445 .BinaryOperation(Token::Value::ADD, builder.Parameter(4))
433 .BinaryOperation(Token::Value::ADD, builder.Parameter(5)) 446 .BinaryOperation(Token::Value::ADD, builder.Parameter(5))
434 .BinaryOperation(Token::Value::ADD, builder.Parameter(6)) 447 .BinaryOperation(Token::Value::ADD, builder.Parameter(6))
435 .BinaryOperation(Token::Value::ADD, builder.Parameter(7)) 448 .BinaryOperation(Token::Value::ADD, builder.Parameter(7))
436 .Return(); 449 .Return();
(...skipping 10 matching lines...) Expand all
447 Handle<Smi> arg5 = Handle<Smi>(Smi::FromInt(5), handles.main_isolate()); 460 Handle<Smi> arg5 = Handle<Smi>(Smi::FromInt(5), handles.main_isolate());
448 Handle<Smi> arg6 = Handle<Smi>(Smi::FromInt(6), handles.main_isolate()); 461 Handle<Smi> arg6 = Handle<Smi>(Smi::FromInt(6), handles.main_isolate());
449 Handle<Smi> arg7 = Handle<Smi>(Smi::FromInt(7), handles.main_isolate()); 462 Handle<Smi> arg7 = Handle<Smi>(Smi::FromInt(7), handles.main_isolate());
450 Handle<Smi> arg8 = Handle<Smi>(Smi::FromInt(8), handles.main_isolate()); 463 Handle<Smi> arg8 = Handle<Smi>(Smi::FromInt(8), handles.main_isolate());
451 // Check for Smis. 464 // Check for Smis.
452 Handle<Object> return_val = 465 Handle<Object> return_val =
453 callable(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) 466 callable(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
454 .ToHandleChecked(); 467 .ToHandleChecked();
455 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(36)); 468 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(36));
456 } 469 }
470
471
472 TEST(InterpreterLoadNamedProperty) {
473 HandleAndZoneScope handles;
474 i::Isolate* isolate = handles.main_isolate();
475 i::Factory* factory = isolate->factory();
476
477 i::Code::Kind ic_kinds[] = { i::Code::LOAD_IC };
478 i::FeedbackVectorSpec feedback_spec(0, 1, ic_kinds);
479 Handle<i::TypeFeedbackVector> vector =
480 factory->NewTypeFeedbackVector(&feedback_spec);
481
482 Handle<i::String> name = factory->NewStringFromAsciiChecked("val");
483 name = factory->string_table()->LookupString(isolate, name);
484
485 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone());
486 builder.set_locals_count(0);
487 builder.set_parameter_count(1);
488 builder.LoadLiteral(name)
489 .LoadNamedProperty(builder.Parameter(0), vector->first_ic_slot_index(),
490 i::SLOPPY)
491 .Return();
492 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
493
494 InterpreterTester tester(handles.main_isolate(), bytecode_array, vector);
495 auto callable = tester.GetCallable<Handle<Object>>();
496
497 Handle<Object> object = tester.NewObject("({ val : 123 })");
498 // Test IC miss.
499 Handle<Object> return_val = callable(object).ToHandleChecked();
500 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(123));
501
502 // Test transition to monomorphic IC.
503 return_val = callable(object).ToHandleChecked();
504 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(123));
505
506 // Test transition to polymorphic IC.
507 Handle<Object> object2 = tester.NewObject("({ val : 456, other : 123 })");
508 return_val = callable(object2).ToHandleChecked();
509 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(456));
510
511 // Test transition to megamorphic IC.
512 Handle<Object> object3 = tester.NewObject("({ val : 789, val2 : 123 })");
513 callable(object3).ToHandleChecked();
514 Handle<Object> object4 = tester.NewObject("({ val : 789, val3 : 123 })");
515 callable(object4).ToHandleChecked();
516 Handle<Object> object5 = tester.NewObject("({ val : 789, val4 : 123 })");
517 return_val = callable(object5).ToHandleChecked();
518 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(789));
519 }
520
521
522 TEST(InterpreterLoadKeyedProperty) {
523 HandleAndZoneScope handles;
524 i::Isolate* isolate = handles.main_isolate();
525 i::Factory* factory = isolate->factory();
526
527 i::Code::Kind ic_kinds[] = { i::Code::KEYED_LOAD_IC };
528 i::FeedbackVectorSpec feedback_spec(0, 1, ic_kinds);
529 Handle<i::TypeFeedbackVector> vector =
530 factory->NewTypeFeedbackVector(&feedback_spec);
531
532 Handle<i::String> key = factory->NewStringFromAsciiChecked("key");
533 key = factory->string_table()->LookupString(isolate, key);
534
535 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone());
536 builder.set_locals_count(1);
537 builder.set_parameter_count(1);
538 builder.LoadLiteral(key)
539 .LoadKeyedProperty(builder.Parameter(0), vector->first_ic_slot_index(),
540 i::SLOPPY)
541 .Return();
542 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
543
544 InterpreterTester tester(handles.main_isolate(), bytecode_array, vector);
545 auto callable = tester.GetCallable<Handle<Object>>();
546
547 Handle<Object> object = tester.NewObject("({ key : 123 })");
548 // Test IC miss.
549 Handle<Object> return_val = callable(object).ToHandleChecked();
550 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(123));
551
552 // Test transition to monomorphic IC.
553 return_val = callable(object).ToHandleChecked();
554 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(123));
555
556 // Test transition to megamorphic IC.
557 Handle<Object> object3 = tester.NewObject("({ key : 789, val2 : 123 })");
558 return_val = callable(object3).ToHandleChecked();
559 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(789));
560 }
OLDNEW
« no previous file with comments | « test/cctest/interpreter/test-bytecode-generator.cc ('k') | test/unittests/compiler/interpreter-assembler-unittest.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698