| Index: test/cctest/interpreter/test-interpreter.cc
|
| diff --git a/test/cctest/interpreter/test-interpreter.cc b/test/cctest/interpreter/test-interpreter.cc
|
| index 56fa4c6257e39a6fb7870224336f1ea996066b71..70997474baaeea753afa34c34995393a7a116182 100644
|
| --- a/test/cctest/interpreter/test-interpreter.cc
|
| +++ b/test/cctest/interpreter/test-interpreter.cc
|
| @@ -59,6 +59,7 @@ class InterpreterTester {
|
| : isolate_(isolate),
|
| bytecode_(bytecode),
|
| feedback_vector_(feedback_vector) {
|
| + i::FLAG_vector_stores = true;
|
| i::FLAG_ignition = true;
|
| // Ensure handler table is generated.
|
| isolate->interpreter()->Initialize();
|
| @@ -109,6 +110,7 @@ class InterpreterTester {
|
| using v8::internal::BytecodeArray;
|
| using v8::internal::Handle;
|
| using v8::internal::Object;
|
| +using v8::internal::Runtime;
|
| using v8::internal::Smi;
|
| using v8::internal::Token;
|
| using namespace v8::internal::interpreter;
|
| @@ -558,3 +560,105 @@ TEST(InterpreterLoadKeyedProperty) {
|
| return_val = callable(object3).ToHandleChecked();
|
| CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(789));
|
| }
|
| +
|
| +
|
| +TEST(InterpreterStoreNamedProperty) {
|
| + HandleAndZoneScope handles;
|
| + i::Isolate* isolate = handles.main_isolate();
|
| + i::Factory* factory = isolate->factory();
|
| +
|
| + i::Code::Kind ic_kinds[] = {i::Code::STORE_IC};
|
| + i::FeedbackVectorSpec feedback_spec(0, 1, ic_kinds);
|
| + Handle<i::TypeFeedbackVector> vector =
|
| + factory->NewTypeFeedbackVector(&feedback_spec);
|
| +
|
| + Handle<i::String> name = factory->NewStringFromAsciiChecked("val");
|
| + name = factory->string_table()->LookupString(isolate, name);
|
| +
|
| + BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone());
|
| + builder.set_locals_count(1);
|
| + builder.set_parameter_count(1);
|
| + builder.LoadLiteral(name)
|
| + .StoreAccumulatorInRegister(Register(0))
|
| + .LoadLiteral(Smi::FromInt(999))
|
| + .StoreNamedProperty(builder.Parameter(0), Register(0),
|
| + vector->first_ic_slot_index(), i::SLOPPY)
|
| + .Return();
|
| + Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
|
| +
|
| + InterpreterTester tester(isolate, bytecode_array, vector);
|
| + auto callable = tester.GetCallable<Handle<Object>>();
|
| + Handle<Object> object = tester.NewObject("({ val : 123 })");
|
| + // Test IC miss.
|
| + Handle<Object> result;
|
| + callable(object).ToHandleChecked();
|
| + CHECK(Runtime::GetObjectProperty(isolate, object, name).ToHandle(&result));
|
| + CHECK_EQ(Smi::cast(*result), Smi::FromInt(999));
|
| +
|
| + // Test transition to monomorphic IC.
|
| + callable(object).ToHandleChecked();
|
| + CHECK(Runtime::GetObjectProperty(isolate, object, name).ToHandle(&result));
|
| + CHECK_EQ(Smi::cast(*result), Smi::FromInt(999));
|
| +
|
| + // Test transition to polymorphic IC.
|
| + Handle<Object> object2 = tester.NewObject("({ val : 456, other : 123 })");
|
| + callable(object2).ToHandleChecked();
|
| + CHECK(Runtime::GetObjectProperty(isolate, object2, name).ToHandle(&result));
|
| + CHECK_EQ(Smi::cast(*result), Smi::FromInt(999));
|
| +
|
| + // Test transition to megamorphic IC.
|
| + Handle<Object> object3 = tester.NewObject("({ val : 789, val2 : 123 })");
|
| + callable(object3).ToHandleChecked();
|
| + Handle<Object> object4 = tester.NewObject("({ val : 789, val3 : 123 })");
|
| + callable(object4).ToHandleChecked();
|
| + Handle<Object> object5 = tester.NewObject("({ val : 789, val4 : 123 })");
|
| + callable(object5).ToHandleChecked();
|
| + CHECK(Runtime::GetObjectProperty(isolate, object5, name).ToHandle(&result));
|
| + CHECK_EQ(Smi::cast(*result), Smi::FromInt(999));
|
| +}
|
| +
|
| +
|
| +TEST(InterpreterStoreKeyedProperty) {
|
| + HandleAndZoneScope handles;
|
| + i::Isolate* isolate = handles.main_isolate();
|
| + i::Factory* factory = isolate->factory();
|
| +
|
| + i::Code::Kind ic_kinds[] = {i::Code::KEYED_STORE_IC};
|
| + i::FeedbackVectorSpec feedback_spec(0, 1, ic_kinds);
|
| + Handle<i::TypeFeedbackVector> vector =
|
| + factory->NewTypeFeedbackVector(&feedback_spec);
|
| +
|
| + Handle<i::String> name = factory->NewStringFromAsciiChecked("val");
|
| + name = factory->string_table()->LookupString(isolate, name);
|
| +
|
| + BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone());
|
| + builder.set_locals_count(1);
|
| + builder.set_parameter_count(1);
|
| + builder.LoadLiteral(name)
|
| + .StoreAccumulatorInRegister(Register(0))
|
| + .LoadLiteral(Smi::FromInt(999))
|
| + .StoreKeyedProperty(builder.Parameter(0), Register(0),
|
| + vector->first_ic_slot_index(), i::SLOPPY)
|
| + .Return();
|
| + Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
|
| +
|
| + InterpreterTester tester(isolate, bytecode_array, vector);
|
| + auto callable = tester.GetCallable<Handle<Object>>();
|
| + Handle<Object> object = tester.NewObject("({ val : 123 })");
|
| + // Test IC miss.
|
| + Handle<Object> result;
|
| + callable(object).ToHandleChecked();
|
| + CHECK(Runtime::GetObjectProperty(isolate, object, name).ToHandle(&result));
|
| + CHECK_EQ(Smi::cast(*result), Smi::FromInt(999));
|
| +
|
| + // Test transition to monomorphic IC.
|
| + callable(object).ToHandleChecked();
|
| + CHECK(Runtime::GetObjectProperty(isolate, object, name).ToHandle(&result));
|
| + CHECK_EQ(Smi::cast(*result), Smi::FromInt(999));
|
| +
|
| + // Test transition to megamorphic IC.
|
| + Handle<Object> object2 = tester.NewObject("({ val : 456, other : 123 })");
|
| + callable(object2).ToHandleChecked();
|
| + CHECK(Runtime::GetObjectProperty(isolate, object2, name).ToHandle(&result));
|
| + CHECK_EQ(Smi::cast(*result), Smi::FromInt(999));
|
| +}
|
|
|