| Index: test/cctest/test-unboxed-doubles.cc
|
| diff --git a/test/cctest/test-unboxed-doubles.cc b/test/cctest/test-unboxed-doubles.cc
|
| deleted file mode 100644
|
| index 2abf3c2926c434a5ff9c2a41ebc55c9dd026bf37..0000000000000000000000000000000000000000
|
| --- a/test/cctest/test-unboxed-doubles.cc
|
| +++ /dev/null
|
| @@ -1,668 +0,0 @@
|
| -// Copyright 2014 the V8 project authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include <stdlib.h>
|
| -#include <utility>
|
| -
|
| -#include "src/v8.h"
|
| -
|
| -#include "src/compilation-cache.h"
|
| -#include "src/execution.h"
|
| -#include "src/factory.h"
|
| -#include "src/global-handles.h"
|
| -#include "src/ic/ic.h"
|
| -#include "src/macro-assembler.h"
|
| -#include "test/cctest/cctest.h"
|
| -
|
| -using namespace v8::base;
|
| -using namespace v8::internal;
|
| -
|
| -#if (V8_DOUBLE_FIELDS_UNBOXING)
|
| -
|
| -
|
| -static double GetDoubleFieldValue(JSObject* obj, FieldIndex field_index) {
|
| - if (obj->IsUnboxedDoubleField(field_index)) {
|
| - return obj->RawFastDoublePropertyAt(field_index);
|
| - } else {
|
| - Object* value = obj->RawFastPropertyAt(field_index);
|
| - DCHECK(value->IsMutableHeapNumber());
|
| - return HeapNumber::cast(value)->value();
|
| - }
|
| -}
|
| -
|
| -
|
| -enum PropertyKind {
|
| - PROP_CONSTANT,
|
| - PROP_SMI,
|
| - PROP_DOUBLE,
|
| - PROP_TAGGED,
|
| - PROP_KIND_NUMBER,
|
| -};
|
| -
|
| -static Representation representations[PROP_KIND_NUMBER] = {
|
| - Representation::None(), Representation::Smi(), Representation::Double(),
|
| - Representation::Tagged()};
|
| -
|
| -
|
| -static Handle<DescriptorArray> CreateDescriptorArray(Isolate* isolate,
|
| - PropertyKind* props,
|
| - int kPropsCount) {
|
| - Factory* factory = isolate->factory();
|
| -
|
| - Handle<String> func_name = factory->InternalizeUtf8String("func");
|
| - Handle<JSFunction> func = factory->NewFunction(func_name);
|
| -
|
| - Handle<DescriptorArray> descriptors =
|
| - DescriptorArray::Allocate(isolate, 0, kPropsCount);
|
| -
|
| - int next_field_offset = 0;
|
| - for (int i = 0; i < kPropsCount; i++) {
|
| - EmbeddedVector<char, 64> buffer;
|
| - SNPrintF(buffer, "prop%d", i);
|
| - Handle<String> name = factory->InternalizeUtf8String(buffer.start());
|
| -
|
| - PropertyKind kind = props[i];
|
| -
|
| - if (kind == PROP_CONSTANT) {
|
| - ConstantDescriptor d(name, func, NONE);
|
| - descriptors->Append(&d);
|
| -
|
| - } else {
|
| - FieldDescriptor f(name, next_field_offset, NONE, representations[kind]);
|
| - next_field_offset += f.GetDetails().field_width_in_words();
|
| - descriptors->Append(&f);
|
| - }
|
| - }
|
| - return descriptors;
|
| -}
|
| -
|
| -
|
| -TEST(LayoutDescriptorBasicFast) {
|
| - CcTest::InitializeVM();
|
| - v8::HandleScope scope(CcTest::isolate());
|
| -
|
| - LayoutDescriptor* layout_desc = LayoutDescriptor::FastPointerLayout();
|
| -
|
| - CHECK(!layout_desc->IsSlowLayout());
|
| - CHECK(layout_desc->IsFastPointerLayout());
|
| - CHECK_EQ(kSmiValueSize, layout_desc->capacity());
|
| -
|
| - for (int i = 0; i < kSmiValueSize + 13; i++) {
|
| - CHECK_EQ(true, layout_desc->IsTagged(i));
|
| - }
|
| - CHECK_EQ(true, layout_desc->IsTagged(-1));
|
| - CHECK_EQ(true, layout_desc->IsTagged(-12347));
|
| - CHECK_EQ(true, layout_desc->IsTagged(15635));
|
| - CHECK(layout_desc->IsFastPointerLayout());
|
| -
|
| - for (int i = 0; i < kSmiValueSize; i++) {
|
| - layout_desc = layout_desc->SetTaggedForTesting(i, false);
|
| - CHECK_EQ(false, layout_desc->IsTagged(i));
|
| - layout_desc = layout_desc->SetTaggedForTesting(i, true);
|
| - CHECK_EQ(true, layout_desc->IsTagged(i));
|
| - }
|
| - CHECK(layout_desc->IsFastPointerLayout());
|
| -}
|
| -
|
| -
|
| -TEST(LayoutDescriptorBasicSlow) {
|
| - CcTest::InitializeVM();
|
| - Isolate* isolate = CcTest::i_isolate();
|
| - v8::HandleScope scope(CcTest::isolate());
|
| -
|
| - Handle<LayoutDescriptor> layout_descriptor;
|
| - const int kPropsCount = kSmiValueSize * 3;
|
| - PropertyKind props[kPropsCount];
|
| - for (int i = 0; i < kPropsCount; i++) {
|
| - // All properties tagged.
|
| - props[i] = PROP_TAGGED;
|
| - }
|
| -
|
| - {
|
| - Handle<DescriptorArray> descriptors =
|
| - CreateDescriptorArray(isolate, props, kPropsCount);
|
| -
|
| - Handle<Map> map = Map::Create(isolate, kPropsCount);
|
| -
|
| - layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
|
| - CHECK_EQ(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
|
| - CHECK_EQ(kSmiValueSize, layout_descriptor->capacity());
|
| - map->InitializeDescriptors(*descriptors, *layout_descriptor);
|
| - DCHECK(layout_descriptor->IsConsistentWithMap(*map));
|
| - }
|
| -
|
| - props[0] = PROP_DOUBLE;
|
| - props[kPropsCount - 1] = PROP_DOUBLE;
|
| -
|
| - Handle<DescriptorArray> descriptors =
|
| - CreateDescriptorArray(isolate, props, kPropsCount);
|
| -
|
| - {
|
| - int inobject_properties = kPropsCount - 1;
|
| - Handle<Map> map = Map::Create(isolate, inobject_properties);
|
| -
|
| - // Should be fast as the only double property is the first one.
|
| - layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
|
| - CHECK_NE(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
|
| - CHECK(!layout_descriptor->IsSlowLayout());
|
| - CHECK(!layout_descriptor->IsFastPointerLayout());
|
| -
|
| - CHECK_EQ(false, layout_descriptor->IsTagged(0));
|
| - for (int i = 1; i < kPropsCount; i++) {
|
| - CHECK_EQ(true, layout_descriptor->IsTagged(i));
|
| - }
|
| - map->InitializeDescriptors(*descriptors, *layout_descriptor);
|
| - DCHECK(layout_descriptor->IsConsistentWithMap(*map));
|
| - }
|
| -
|
| - {
|
| - int inobject_properties = kPropsCount;
|
| - Handle<Map> map = Map::Create(isolate, inobject_properties);
|
| -
|
| - layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
|
| - CHECK_NE(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
|
| - CHECK(layout_descriptor->IsSlowLayout());
|
| - CHECK(!layout_descriptor->IsFastPointerLayout());
|
| - CHECK(layout_descriptor->capacity() > kSmiValueSize);
|
| -
|
| - CHECK_EQ(false, layout_descriptor->IsTagged(0));
|
| - CHECK_EQ(false, layout_descriptor->IsTagged(kPropsCount - 1));
|
| - for (int i = 1; i < kPropsCount - 1; i++) {
|
| - CHECK_EQ(true, layout_descriptor->IsTagged(i));
|
| - }
|
| -
|
| - map->InitializeDescriptors(*descriptors, *layout_descriptor);
|
| - DCHECK(layout_descriptor->IsConsistentWithMap(*map));
|
| -
|
| - // Here we have truly slow layout descriptor, so play with the bits.
|
| - CHECK_EQ(true, layout_descriptor->IsTagged(-1));
|
| - CHECK_EQ(true, layout_descriptor->IsTagged(-12347));
|
| - CHECK_EQ(true, layout_descriptor->IsTagged(15635));
|
| -
|
| - LayoutDescriptor* layout_desc = *layout_descriptor;
|
| - // Play with the bits but leave it in consistent state with map at the end.
|
| - for (int i = 1; i < kPropsCount - 1; i++) {
|
| - layout_desc = layout_desc->SetTaggedForTesting(i, false);
|
| - CHECK_EQ(false, layout_desc->IsTagged(i));
|
| - layout_desc = layout_desc->SetTaggedForTesting(i, true);
|
| - CHECK_EQ(true, layout_desc->IsTagged(i));
|
| - }
|
| - CHECK(layout_desc->IsSlowLayout());
|
| - CHECK(!layout_desc->IsFastPointerLayout());
|
| -
|
| - DCHECK(layout_descriptor->IsConsistentWithMap(*map));
|
| - }
|
| -}
|
| -
|
| -
|
| -TEST(LayoutDescriptorCreateNewFast) {
|
| - CcTest::InitializeVM();
|
| - Isolate* isolate = CcTest::i_isolate();
|
| - v8::HandleScope scope(CcTest::isolate());
|
| -
|
| - Handle<LayoutDescriptor> layout_descriptor;
|
| - PropertyKind props[] = {
|
| - PROP_CONSTANT,
|
| - PROP_TAGGED, // field #0
|
| - PROP_CONSTANT,
|
| - PROP_DOUBLE, // field #1
|
| - PROP_CONSTANT,
|
| - PROP_TAGGED, // field #2
|
| - PROP_CONSTANT,
|
| - };
|
| - const int kPropsCount = arraysize(props);
|
| -
|
| - Handle<DescriptorArray> descriptors =
|
| - CreateDescriptorArray(isolate, props, kPropsCount);
|
| -
|
| - {
|
| - Handle<Map> map = Map::Create(isolate, 0);
|
| - layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
|
| - CHECK_EQ(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
|
| - map->InitializeDescriptors(*descriptors, *layout_descriptor);
|
| - DCHECK(layout_descriptor->IsConsistentWithMap(*map));
|
| - }
|
| -
|
| - {
|
| - Handle<Map> map = Map::Create(isolate, 1);
|
| - layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
|
| - CHECK_EQ(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
|
| - map->InitializeDescriptors(*descriptors, *layout_descriptor);
|
| - DCHECK(layout_descriptor->IsConsistentWithMap(*map));
|
| - }
|
| -
|
| - {
|
| - Handle<Map> map = Map::Create(isolate, 2);
|
| - layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
|
| - CHECK_NE(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
|
| - CHECK(!layout_descriptor->IsSlowLayout());
|
| - CHECK_EQ(true, layout_descriptor->IsTagged(0));
|
| - CHECK_EQ(false, layout_descriptor->IsTagged(1));
|
| - CHECK_EQ(true, layout_descriptor->IsTagged(2));
|
| - CHECK_EQ(true, layout_descriptor->IsTagged(125));
|
| - map->InitializeDescriptors(*descriptors, *layout_descriptor);
|
| - DCHECK(layout_descriptor->IsConsistentWithMap(*map));
|
| - }
|
| -}
|
| -
|
| -
|
| -TEST(LayoutDescriptorCreateNewSlow) {
|
| - CcTest::InitializeVM();
|
| - Isolate* isolate = CcTest::i_isolate();
|
| - v8::HandleScope scope(CcTest::isolate());
|
| -
|
| - Handle<LayoutDescriptor> layout_descriptor;
|
| - const int kPropsCount = kSmiValueSize * 3;
|
| - PropertyKind props[kPropsCount];
|
| - for (int i = 0; i < kPropsCount; i++) {
|
| - props[i] = static_cast<PropertyKind>(i % PROP_KIND_NUMBER);
|
| - }
|
| -
|
| - Handle<DescriptorArray> descriptors =
|
| - CreateDescriptorArray(isolate, props, kPropsCount);
|
| -
|
| - {
|
| - Handle<Map> map = Map::Create(isolate, 0);
|
| - layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
|
| - CHECK_EQ(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
|
| - map->InitializeDescriptors(*descriptors, *layout_descriptor);
|
| - DCHECK(layout_descriptor->IsConsistentWithMap(*map));
|
| - }
|
| -
|
| - {
|
| - Handle<Map> map = Map::Create(isolate, 1);
|
| - layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
|
| - CHECK_EQ(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
|
| - map->InitializeDescriptors(*descriptors, *layout_descriptor);
|
| - DCHECK(layout_descriptor->IsConsistentWithMap(*map));
|
| - }
|
| -
|
| - {
|
| - Handle<Map> map = Map::Create(isolate, 2);
|
| - layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
|
| - CHECK_NE(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
|
| - CHECK(!layout_descriptor->IsSlowLayout());
|
| - CHECK_EQ(true, layout_descriptor->IsTagged(0));
|
| - CHECK_EQ(false, layout_descriptor->IsTagged(1));
|
| - CHECK_EQ(true, layout_descriptor->IsTagged(2));
|
| - CHECK_EQ(true, layout_descriptor->IsTagged(125));
|
| - map->InitializeDescriptors(*descriptors, *layout_descriptor);
|
| - DCHECK(layout_descriptor->IsConsistentWithMap(*map));
|
| - }
|
| -
|
| - {
|
| - int inobject_properties = kPropsCount / 2;
|
| - Handle<Map> map = Map::Create(isolate, inobject_properties);
|
| - layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
|
| - CHECK_NE(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
|
| - CHECK(layout_descriptor->IsSlowLayout());
|
| - for (int i = 0; i < inobject_properties; i++) {
|
| - // PROP_DOUBLE has index 1 among FIELD properties.
|
| - const bool tagged = (i % (PROP_KIND_NUMBER - 1)) != 1;
|
| - CHECK_EQ(tagged, layout_descriptor->IsTagged(i));
|
| - }
|
| - // Every property after inobject_properties must be tagged.
|
| - for (int i = inobject_properties; i < kPropsCount; i++) {
|
| - CHECK_EQ(true, layout_descriptor->IsTagged(i));
|
| - }
|
| - map->InitializeDescriptors(*descriptors, *layout_descriptor);
|
| - DCHECK(layout_descriptor->IsConsistentWithMap(*map));
|
| -
|
| - // Now test LayoutDescriptor::cast_gc_safe().
|
| - Handle<LayoutDescriptor> layout_descriptor_copy =
|
| - LayoutDescriptor::New(map, descriptors, kPropsCount);
|
| -
|
| - LayoutDescriptor* layout_desc = *layout_descriptor;
|
| - CHECK_EQ(layout_desc, LayoutDescriptor::cast(layout_desc));
|
| - CHECK_EQ(layout_desc, LayoutDescriptor::cast_gc_safe(layout_desc));
|
| - CHECK(layout_descriptor->IsFixedTypedArrayBase());
|
| - // Now make it look like a forwarding pointer to layout_descriptor_copy.
|
| - MapWord map_word = layout_desc->map_word();
|
| - CHECK(!map_word.IsForwardingAddress());
|
| - layout_desc->set_map_word(
|
| - MapWord::FromForwardingAddress(*layout_descriptor_copy));
|
| - CHECK(layout_desc->map_word().IsForwardingAddress());
|
| - CHECK_EQ(*layout_descriptor_copy,
|
| - LayoutDescriptor::cast_gc_safe(layout_desc));
|
| -
|
| - // Restore it back.
|
| - layout_desc->set_map_word(map_word);
|
| - CHECK_EQ(layout_desc, LayoutDescriptor::cast(layout_desc));
|
| - }
|
| -}
|
| -
|
| -
|
| -static Handle<LayoutDescriptor> TestLayoutDescriptorAppend(
|
| - Isolate* isolate, int inobject_properties, PropertyKind* props,
|
| - int kPropsCount) {
|
| - Factory* factory = isolate->factory();
|
| -
|
| - Handle<String> func_name = factory->InternalizeUtf8String("func");
|
| - Handle<JSFunction> func = factory->NewFunction(func_name);
|
| -
|
| - Handle<DescriptorArray> descriptors =
|
| - DescriptorArray::Allocate(isolate, 0, kPropsCount);
|
| -
|
| - Handle<Map> map = Map::Create(isolate, inobject_properties);
|
| - map->InitializeDescriptors(*descriptors,
|
| - LayoutDescriptor::FastPointerLayout());
|
| -
|
| - int next_field_offset = 0;
|
| - for (int i = 0; i < kPropsCount; i++) {
|
| - EmbeddedVector<char, 64> buffer;
|
| - SNPrintF(buffer, "prop%d", i);
|
| - Handle<String> name = factory->InternalizeUtf8String(buffer.start());
|
| -
|
| - Handle<LayoutDescriptor> layout_descriptor;
|
| - PropertyKind kind = props[i];
|
| - if (kind == PROP_CONSTANT) {
|
| - ConstantDescriptor d(name, func, NONE);
|
| - layout_descriptor = LayoutDescriptor::Append(map, d.GetDetails());
|
| - descriptors->Append(&d);
|
| -
|
| - } else {
|
| - FieldDescriptor f(name, next_field_offset, NONE, representations[kind]);
|
| - int field_width_in_words = f.GetDetails().field_width_in_words();
|
| - next_field_offset += field_width_in_words;
|
| - layout_descriptor = LayoutDescriptor::Append(map, f.GetDetails());
|
| - descriptors->Append(&f);
|
| -
|
| - int field_index = f.GetDetails().field_index();
|
| - bool is_inobject = field_index < map->inobject_properties();
|
| - for (int bit = 0; bit < field_width_in_words; bit++) {
|
| - CHECK_EQ(is_inobject && (kind == PROP_DOUBLE),
|
| - !layout_descriptor->IsTagged(field_index + bit));
|
| - }
|
| - CHECK(layout_descriptor->IsTagged(next_field_offset));
|
| - }
|
| - map->InitializeDescriptors(*descriptors, *layout_descriptor);
|
| - }
|
| - Handle<LayoutDescriptor> layout_descriptor(map->layout_descriptor(), isolate);
|
| - DCHECK(layout_descriptor->IsConsistentWithMap(*map));
|
| - return layout_descriptor;
|
| -}
|
| -
|
| -
|
| -TEST(LayoutDescriptorAppend) {
|
| - CcTest::InitializeVM();
|
| - Isolate* isolate = CcTest::i_isolate();
|
| - v8::HandleScope scope(CcTest::isolate());
|
| -
|
| - Handle<LayoutDescriptor> layout_descriptor;
|
| - const int kPropsCount = kSmiValueSize * 3;
|
| - PropertyKind props[kPropsCount];
|
| - for (int i = 0; i < kPropsCount; i++) {
|
| - props[i] = static_cast<PropertyKind>(i % PROP_KIND_NUMBER);
|
| - }
|
| -
|
| - layout_descriptor =
|
| - TestLayoutDescriptorAppend(isolate, 0, props, kPropsCount);
|
| - CHECK(!layout_descriptor->IsSlowLayout());
|
| -
|
| - layout_descriptor =
|
| - TestLayoutDescriptorAppend(isolate, 13, props, kPropsCount);
|
| - CHECK(!layout_descriptor->IsSlowLayout());
|
| -
|
| - layout_descriptor =
|
| - TestLayoutDescriptorAppend(isolate, kSmiValueSize, props, kPropsCount);
|
| - CHECK(!layout_descriptor->IsSlowLayout());
|
| -
|
| - layout_descriptor = TestLayoutDescriptorAppend(isolate, kSmiValueSize * 2,
|
| - props, kPropsCount);
|
| - CHECK(layout_descriptor->IsSlowLayout());
|
| -
|
| - layout_descriptor =
|
| - TestLayoutDescriptorAppend(isolate, kPropsCount, props, kPropsCount);
|
| - CHECK(layout_descriptor->IsSlowLayout());
|
| -}
|
| -
|
| -
|
| -TEST(LayoutDescriptorAppendAllDoubles) {
|
| - CcTest::InitializeVM();
|
| - Isolate* isolate = CcTest::i_isolate();
|
| - v8::HandleScope scope(CcTest::isolate());
|
| -
|
| - Handle<LayoutDescriptor> layout_descriptor;
|
| - const int kPropsCount = kSmiValueSize * 3;
|
| - PropertyKind props[kPropsCount];
|
| - for (int i = 0; i < kPropsCount; i++) {
|
| - props[i] = PROP_DOUBLE;
|
| - }
|
| -
|
| - layout_descriptor =
|
| - TestLayoutDescriptorAppend(isolate, 0, props, kPropsCount);
|
| - CHECK(!layout_descriptor->IsSlowLayout());
|
| -
|
| - layout_descriptor =
|
| - TestLayoutDescriptorAppend(isolate, 13, props, kPropsCount);
|
| - CHECK(!layout_descriptor->IsSlowLayout());
|
| -
|
| - layout_descriptor =
|
| - TestLayoutDescriptorAppend(isolate, kSmiValueSize, props, kPropsCount);
|
| - CHECK(!layout_descriptor->IsSlowLayout());
|
| -
|
| - layout_descriptor = TestLayoutDescriptorAppend(isolate, kSmiValueSize + 1,
|
| - props, kPropsCount);
|
| - CHECK(layout_descriptor->IsSlowLayout());
|
| -
|
| - layout_descriptor = TestLayoutDescriptorAppend(isolate, kSmiValueSize * 2,
|
| - props, kPropsCount);
|
| - CHECK(layout_descriptor->IsSlowLayout());
|
| -
|
| - layout_descriptor =
|
| - TestLayoutDescriptorAppend(isolate, kPropsCount, props, kPropsCount);
|
| - CHECK(layout_descriptor->IsSlowLayout());
|
| -
|
| - {
|
| - // Ensure layout descriptor switches into slow mode at the right moment.
|
| - layout_descriptor =
|
| - TestLayoutDescriptorAppend(isolate, kPropsCount, props, kSmiValueSize);
|
| - CHECK(!layout_descriptor->IsSlowLayout());
|
| -
|
| - layout_descriptor = TestLayoutDescriptorAppend(isolate, kPropsCount, props,
|
| - kSmiValueSize + 1);
|
| - CHECK(layout_descriptor->IsSlowLayout());
|
| - }
|
| -}
|
| -
|
| -
|
| -static Handle<LayoutDescriptor> TestLayoutDescriptorAppendIfFastOrUseFull(
|
| - Isolate* isolate, int inobject_properties,
|
| - Handle<DescriptorArray> descriptors, int number_of_descriptors) {
|
| - Handle<Map> map = Map::Create(isolate, inobject_properties);
|
| -
|
| - Handle<LayoutDescriptor> full_layout_descriptor = LayoutDescriptor::New(
|
| - map, descriptors, descriptors->number_of_descriptors());
|
| -
|
| - int nof = 0;
|
| - bool switched_to_slow_mode = false;
|
| -
|
| - for (int i = 0; i < number_of_descriptors; i++) {
|
| - PropertyDetails details = descriptors->GetDetails(i);
|
| -
|
| - // This method calls LayoutDescriptor::AppendIfFastOrUseFull() internally
|
| - // and does all the required map-descriptors related book keeping.
|
| - map = Map::CopyInstallDescriptorsForTesting(map, i, descriptors,
|
| - full_layout_descriptor);
|
| -
|
| - LayoutDescriptor* layout_desc = map->layout_descriptor();
|
| -
|
| - if (layout_desc->IsSlowLayout()) {
|
| - switched_to_slow_mode = true;
|
| - CHECK_EQ(*full_layout_descriptor, layout_desc);
|
| - } else {
|
| - CHECK(!switched_to_slow_mode);
|
| - if (details.type() == FIELD) {
|
| - nof++;
|
| - int field_index = details.field_index();
|
| - int field_width_in_words = details.field_width_in_words();
|
| -
|
| - bool is_inobject = field_index < map->inobject_properties();
|
| - for (int bit = 0; bit < field_width_in_words; bit++) {
|
| - CHECK_EQ(is_inobject && details.representation().IsDouble(),
|
| - !layout_desc->IsTagged(field_index + bit));
|
| - }
|
| - CHECK(layout_desc->IsTagged(field_index + field_width_in_words));
|
| - }
|
| - }
|
| - DCHECK(map->layout_descriptor()->IsConsistentWithMap(*map));
|
| - }
|
| -
|
| - Handle<LayoutDescriptor> layout_descriptor = map->GetLayoutDescriptor();
|
| - DCHECK(layout_descriptor->IsConsistentWithMap(*map));
|
| - return layout_descriptor;
|
| -}
|
| -
|
| -
|
| -TEST(LayoutDescriptorAppendIfFastOrUseFull) {
|
| - CcTest::InitializeVM();
|
| - Isolate* isolate = CcTest::i_isolate();
|
| - v8::HandleScope scope(CcTest::isolate());
|
| -
|
| - Handle<LayoutDescriptor> layout_descriptor;
|
| - const int kPropsCount = kSmiValueSize * 3;
|
| - PropertyKind props[kPropsCount];
|
| - for (int i = 0; i < kPropsCount; i++) {
|
| - props[i] = static_cast<PropertyKind>(i % PROP_KIND_NUMBER);
|
| - }
|
| - Handle<DescriptorArray> descriptors =
|
| - CreateDescriptorArray(isolate, props, kPropsCount);
|
| -
|
| - layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
|
| - isolate, 0, descriptors, kPropsCount);
|
| - CHECK(!layout_descriptor->IsSlowLayout());
|
| -
|
| - layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
|
| - isolate, 13, descriptors, kPropsCount);
|
| - CHECK(!layout_descriptor->IsSlowLayout());
|
| -
|
| - layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
|
| - isolate, kSmiValueSize, descriptors, kPropsCount);
|
| - CHECK(!layout_descriptor->IsSlowLayout());
|
| -
|
| - layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
|
| - isolate, kSmiValueSize * 2, descriptors, kPropsCount);
|
| - CHECK(layout_descriptor->IsSlowLayout());
|
| -
|
| - layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
|
| - isolate, kPropsCount, descriptors, kPropsCount);
|
| - CHECK(layout_descriptor->IsSlowLayout());
|
| -}
|
| -
|
| -
|
| -TEST(LayoutDescriptorAppendIfFastOrUseFullAllDoubles) {
|
| - CcTest::InitializeVM();
|
| - Isolate* isolate = CcTest::i_isolate();
|
| - v8::HandleScope scope(CcTest::isolate());
|
| -
|
| - Handle<LayoutDescriptor> layout_descriptor;
|
| - const int kPropsCount = kSmiValueSize * 3;
|
| - PropertyKind props[kPropsCount];
|
| - for (int i = 0; i < kPropsCount; i++) {
|
| - props[i] = PROP_DOUBLE;
|
| - }
|
| - Handle<DescriptorArray> descriptors =
|
| - CreateDescriptorArray(isolate, props, kPropsCount);
|
| -
|
| - layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
|
| - isolate, 0, descriptors, kPropsCount);
|
| - CHECK(!layout_descriptor->IsSlowLayout());
|
| -
|
| - layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
|
| - isolate, 13, descriptors, kPropsCount);
|
| - CHECK(!layout_descriptor->IsSlowLayout());
|
| -
|
| - layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
|
| - isolate, kSmiValueSize, descriptors, kPropsCount);
|
| - CHECK(!layout_descriptor->IsSlowLayout());
|
| -
|
| - layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
|
| - isolate, kSmiValueSize + 1, descriptors, kPropsCount);
|
| - CHECK(layout_descriptor->IsSlowLayout());
|
| -
|
| - layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
|
| - isolate, kSmiValueSize * 2, descriptors, kPropsCount);
|
| - CHECK(layout_descriptor->IsSlowLayout());
|
| -
|
| - layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
|
| - isolate, kPropsCount, descriptors, kPropsCount);
|
| - CHECK(layout_descriptor->IsSlowLayout());
|
| -
|
| - {
|
| - // Ensure layout descriptor switches into slow mode at the right moment.
|
| - layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
|
| - isolate, kPropsCount, descriptors, kSmiValueSize);
|
| - CHECK(!layout_descriptor->IsSlowLayout());
|
| -
|
| - layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
|
| - isolate, kPropsCount, descriptors, kSmiValueSize + 1);
|
| - CHECK(layout_descriptor->IsSlowLayout());
|
| - }
|
| -}
|
| -
|
| -
|
| -TEST(StoreBufferScanOnScavenge) {
|
| - 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
|
| - CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now
|
| -
|
| - CHECK(isolate->heap()->old_pointer_space()->Contains(*obj));
|
| -
|
| - // 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);
|
| - obj->FastPropertyAtPut(field_index,
|
| - *factory->NewHeapNumber(boom_value, MUTABLE));
|
| -
|
| - // Enforce scan on scavenge for the obj's page.
|
| - MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address());
|
| - chunk->set_scan_on_scavenge(true);
|
| -
|
| - // Trigger GCs and force evacuation. Should not crash there.
|
| - CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
|
| -
|
| - CHECK_EQ(boom_value, GetDoubleFieldValue(*obj, field_index));
|
| -}
|
| -
|
| -#endif
|
|
|