| Index: test/cctest/test-unboxed-doubles.cc
|
| diff --git a/test/cctest/test-unboxed-doubles.cc b/test/cctest/test-unboxed-doubles.cc
|
| index 8b2c47357fe81d973d5d65444fe80db0f7585c2c..1482a7bf0df421e2b92f633381e96ef825faabd1 100644
|
| --- a/test/cctest/test-unboxed-doubles.cc
|
| +++ b/test/cctest/test-unboxed-doubles.cc
|
| @@ -648,6 +648,66 @@ TEST(Regress436816) {
|
| }
|
|
|
|
|
| +TEST(DoScavenge) {
|
| + CcTest::InitializeVM();
|
| + Isolate* isolate = CcTest::i_isolate();
|
| + Factory* factory = isolate->factory();
|
| + v8::HandleScope scope(CcTest::isolate());
|
| +
|
| + CompileRun(
|
| + "function A() {"
|
| + " this.x = 42.5;"
|
| + " this.o = {};"
|
| + "};"
|
| + "var o = new A();");
|
| +
|
| + Handle<String> obj_name = factory->InternalizeUtf8String("o");
|
| +
|
| + Handle<Object> obj_value =
|
| + Object::GetProperty(isolate->global_object(), obj_name).ToHandleChecked();
|
| + CHECK(obj_value->IsJSObject());
|
| + Handle<JSObject> obj = Handle<JSObject>::cast(obj_value);
|
| +
|
| + {
|
| + // Ensure the object is properly set up.
|
| + Map* map = obj->map();
|
| + DescriptorArray* descriptors = map->instance_descriptors();
|
| + CHECK(map->NumberOfOwnDescriptors() == 2);
|
| + CHECK(descriptors->GetDetails(0).representation().IsDouble());
|
| + CHECK(descriptors->GetDetails(1).representation().IsHeapObject());
|
| + FieldIndex field_index = FieldIndex::ForDescriptor(map, 0);
|
| + CHECK(field_index.is_inobject() && field_index.is_double());
|
| + CHECK_EQ(FLAG_unbox_double_fields, map->IsUnboxedDoubleField(field_index));
|
| + CHECK_EQ(42.5, GetDoubleFieldValue(*obj, field_index));
|
| + }
|
| + CHECK(isolate->heap()->new_space()->Contains(*obj));
|
| +
|
| + // Trigger GCs so that the newly allocated object moves to old gen.
|
| + CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now
|
| +
|
| + // Create temp object in the new space.
|
| + Handle<JSArray> temp = factory->NewJSArray(FAST_ELEMENTS, NOT_TENURED);
|
| + CHECK(isolate->heap()->new_space()->Contains(*temp));
|
| +
|
| + // Construct a double value that looks like a pointer to the new space object
|
| + // and store it into the obj.
|
| + Address fake_object = reinterpret_cast<Address>(*temp) + kPointerSize;
|
| + double boom_value = bit_cast<double>(fake_object);
|
| +
|
| + FieldIndex field_index = FieldIndex::ForDescriptor(obj->map(), 0);
|
| + Handle<HeapNumber> boom_number = factory->NewHeapNumber(boom_value, MUTABLE);
|
| + obj->FastPropertyAtPut(field_index, *boom_number);
|
| +
|
| + // Now the object moves to old gen and it has a double field that looks like
|
| + // a pointer to a from semi-space.
|
| + CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now
|
| +
|
| + CHECK(isolate->heap()->old_pointer_space()->Contains(*obj));
|
| +
|
| + CHECK_EQ(boom_value, GetDoubleFieldValue(*obj, field_index));
|
| +}
|
| +
|
| +
|
| TEST(StoreBufferScanOnScavenge) {
|
| CcTest::InitializeVM();
|
| Isolate* isolate = CcTest::i_isolate();
|
|
|