| Index: src/objects-inl.h
|
| diff --git a/src/objects-inl.h b/src/objects-inl.h
|
| index 9564ff0be077f56e1e3abd8361f5c778b4ae0dfb..e7dcd631a85eadf901eb9c36659d067e49f81998 100644
|
| --- a/src/objects-inl.h
|
| +++ b/src/objects-inl.h
|
| @@ -26,6 +26,7 @@
|
| #include "src/heap/spaces.h"
|
| #include "src/heap/store-buffer.h"
|
| #include "src/isolate.h"
|
| +#include "src/layout-descriptor-inl.h"
|
| #include "src/lookup.h"
|
| #include "src/objects.h"
|
| #include "src/property.h"
|
| @@ -56,6 +57,14 @@ PropertyDetails PropertyDetails::AsDeleted() const {
|
| }
|
|
|
|
|
| +int PropertyDetails::field_width_in_words() const {
|
| + DCHECK(type() == FIELD);
|
| + if (!FLAG_unbox_double_fields) return 1;
|
| + if (kDoubleSize == kPointerSize) return 1;
|
| + return representation().IsDouble() ? kDoubleSize / kPointerSize : 1;
|
| +}
|
| +
|
| +
|
| #define TYPE_CHECKER(type, instancetype) \
|
| bool Object::Is##type() const { \
|
| return Object::IsHeapObject() && \
|
| @@ -699,6 +708,11 @@ bool Object::IsDescriptorArray() const {
|
| }
|
|
|
|
|
| +bool Object::IsLayoutDescriptor() const {
|
| + return IsSmi() || IsFixedTypedArrayBase();
|
| +}
|
| +
|
| +
|
| bool Object::IsTransitionArray() const {
|
| return IsFixedArray();
|
| }
|
| @@ -2065,10 +2079,24 @@ void JSObject::SetInternalField(int index, Smi* value) {
|
| }
|
|
|
|
|
| +bool JSObject::IsUnboxedDoubleField(FieldIndex index) {
|
| + if (!FLAG_unbox_double_fields) return false;
|
| + return map()->IsUnboxedDoubleField(index);
|
| +}
|
| +
|
| +
|
| +bool Map::IsUnboxedDoubleField(FieldIndex index) {
|
| + if (!FLAG_unbox_double_fields) return false;
|
| + if (index.is_hidden_field() || !index.is_inobject()) return false;
|
| + return !layout_descriptor()->IsTagged(index.property_index());
|
| +}
|
| +
|
| +
|
| // Access fast-case object properties at index. The use of these routines
|
| // is needed to correctly distinguish between properties stored in-object and
|
| // properties stored in the properties array.
|
| Object* JSObject::RawFastPropertyAt(FieldIndex index) {
|
| + DCHECK(!IsUnboxedDoubleField(index));
|
| if (index.is_inobject()) {
|
| return READ_FIELD(this, index.offset());
|
| } else {
|
| @@ -2077,7 +2105,13 @@ Object* JSObject::RawFastPropertyAt(FieldIndex index) {
|
| }
|
|
|
|
|
| -void JSObject::FastPropertyAtPut(FieldIndex index, Object* value) {
|
| +double JSObject::RawFastDoublePropertyAt(FieldIndex index) {
|
| + DCHECK(IsUnboxedDoubleField(index));
|
| + return READ_DOUBLE_FIELD(this, index.offset());
|
| +}
|
| +
|
| +
|
| +void JSObject::RawFastPropertyAtPut(FieldIndex index, Object* value) {
|
| if (index.is_inobject()) {
|
| int offset = index.offset();
|
| WRITE_FIELD(this, offset, value);
|
| @@ -2088,6 +2122,21 @@ void JSObject::FastPropertyAtPut(FieldIndex index, Object* value) {
|
| }
|
|
|
|
|
| +void JSObject::RawFastDoublePropertyAtPut(FieldIndex index, double value) {
|
| + WRITE_DOUBLE_FIELD(this, index.offset(), value);
|
| +}
|
| +
|
| +
|
| +void JSObject::FastPropertyAtPut(FieldIndex index, Object* value) {
|
| + if (IsUnboxedDoubleField(index)) {
|
| + DCHECK(value->IsMutableHeapNumber());
|
| + RawFastDoublePropertyAtPut(index, HeapNumber::cast(value)->value());
|
| + } else {
|
| + RawFastPropertyAtPut(index, value);
|
| + }
|
| +}
|
| +
|
| +
|
| int JSObject::GetInObjectPropertyOffset(int index) {
|
| return map()->GetInObjectPropertyOffset(index);
|
| }
|
| @@ -3106,8 +3155,7 @@ void DescriptorArray::Set(int descriptor_number,
|
| NoIncrementalWriteBarrierSet(this,
|
| ToValueIndex(descriptor_number),
|
| *desc->GetValue());
|
| - NoIncrementalWriteBarrierSet(this,
|
| - ToDetailsIndex(descriptor_number),
|
| + NoIncrementalWriteBarrierSet(this, ToDetailsIndex(descriptor_number),
|
| desc->GetDetails().AsSmi());
|
| }
|
|
|
| @@ -3282,6 +3330,7 @@ CAST_ACCESSOR(JSTypedArray)
|
| CAST_ACCESSOR(JSValue)
|
| CAST_ACCESSOR(JSWeakMap)
|
| CAST_ACCESSOR(JSWeakSet)
|
| +CAST_ACCESSOR(LayoutDescriptor)
|
| CAST_ACCESSOR(Map)
|
| CAST_ACCESSOR(Name)
|
| CAST_ACCESSOR(NameDictionary)
|
| @@ -4323,6 +4372,14 @@ int Map::GetInObjectPropertyOffset(int index) {
|
| }
|
|
|
|
|
| +Handle<Map> Map::CopyInstallDescriptorsForTesting(
|
| + Handle<Map> map, int new_descriptor, Handle<DescriptorArray> descriptors,
|
| + Handle<LayoutDescriptor> layout_descriptor) {
|
| + return CopyInstallDescriptors(map, new_descriptor, descriptors,
|
| + layout_descriptor);
|
| +}
|
| +
|
| +
|
| int HeapObject::SizeFromMap(Map* map) {
|
| int instance_size = map->instance_size();
|
| if (instance_size != kVariableSizeSentinel) return instance_size;
|
| @@ -5168,14 +5225,41 @@ static void EnsureHasTransitionArray(Handle<Map> map) {
|
| }
|
|
|
|
|
| -void Map::InitializeDescriptors(DescriptorArray* descriptors) {
|
| +LayoutDescriptor* Map::layout_descriptor_gc_safe() {
|
| + Object* layout_desc = READ_FIELD(this, kLayoutDecriptorOffset);
|
| + return LayoutDescriptor::cast_gc_safe(layout_desc);
|
| +}
|
| +
|
| +
|
| +void Map::UpdateDescriptors(DescriptorArray* descriptors,
|
| + LayoutDescriptor* layout_desc) {
|
| + set_instance_descriptors(descriptors);
|
| + if (FLAG_unbox_double_fields) {
|
| + if (layout_descriptor()->IsSlowLayout()) {
|
| + set_layout_descriptor(layout_desc);
|
| + }
|
| + SLOW_DCHECK(layout_descriptor()->IsConsistentWithMap(this));
|
| + DCHECK(visitor_id() == StaticVisitorBase::GetVisitorId(this));
|
| + }
|
| +}
|
| +
|
| +
|
| +void Map::InitializeDescriptors(DescriptorArray* descriptors,
|
| + LayoutDescriptor* layout_desc) {
|
| int len = descriptors->number_of_descriptors();
|
| set_instance_descriptors(descriptors);
|
| SetNumberOfOwnDescriptors(len);
|
| +
|
| + if (FLAG_unbox_double_fields) {
|
| + set_layout_descriptor(layout_desc);
|
| + SLOW_DCHECK(layout_descriptor()->IsConsistentWithMap(this));
|
| + set_visitor_id(StaticVisitorBase::GetVisitorId(this));
|
| + }
|
| }
|
|
|
|
|
| ACCESSORS(Map, instance_descriptors, DescriptorArray, kDescriptorsOffset)
|
| +ACCESSORS(Map, layout_descriptor, LayoutDescriptor, kLayoutDecriptorOffset)
|
|
|
|
|
| void Map::set_bit_field3(uint32_t bits) {
|
| @@ -5191,12 +5275,25 @@ uint32_t Map::bit_field3() {
|
| }
|
|
|
|
|
| +LayoutDescriptor* Map::GetLayoutDescriptor() {
|
| + return FLAG_unbox_double_fields ? layout_descriptor()
|
| + : LayoutDescriptor::FastPointerLayout();
|
| +}
|
| +
|
| +
|
| void Map::AppendDescriptor(Descriptor* desc) {
|
| DescriptorArray* descriptors = instance_descriptors();
|
| int number_of_own_descriptors = NumberOfOwnDescriptors();
|
| DCHECK(descriptors->number_of_descriptors() == number_of_own_descriptors);
|
| descriptors->Append(desc);
|
| SetNumberOfOwnDescriptors(number_of_own_descriptors + 1);
|
| +
|
| +// This function does not support appending double field descriptors and
|
| +// it should never try to (otherwise, layout descriptor must be updated too).
|
| +#ifdef DEBUG
|
| + PropertyDetails details = desc->GetDetails();
|
| + CHECK(details.type() != FIELD || !details.representation().IsDouble());
|
| +#endif
|
| }
|
|
|
|
|
| @@ -7273,12 +7370,37 @@ void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
|
| }
|
|
|
|
|
| +static inline void IterateBodyUsingLayoutDescriptor(HeapObject* object,
|
| + int start_offset,
|
| + int end_offset,
|
| + ObjectVisitor* v) {
|
| + DCHECK(FLAG_unbox_double_fields);
|
| + DCHECK(IsAligned(start_offset, kPointerSize) &&
|
| + IsAligned(end_offset, kPointerSize));
|
| +
|
| + InobjectPropertiesHelper helper(object->map());
|
| + DCHECK(!helper.all_fields_tagged());
|
| +
|
| + for (int offset = start_offset; offset < end_offset; offset += kPointerSize) {
|
| + // Visit all tagged fields.
|
| + if (helper.IsTagged(offset)) {
|
| + v->VisitPointer(HeapObject::RawField(object, offset));
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| template<int start_offset, int end_offset, int size>
|
| void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
|
| HeapObject* obj,
|
| ObjectVisitor* v) {
|
| + if (!FLAG_unbox_double_fields ||
|
| + obj->map()->layout_descriptor()->IsFastPointerLayout()) {
|
| v->VisitPointers(HeapObject::RawField(obj, start_offset),
|
| HeapObject::RawField(obj, end_offset));
|
| + } else {
|
| + IterateBodyUsingLayoutDescriptor(obj, start_offset, end_offset, v);
|
| + }
|
| }
|
|
|
|
|
| @@ -7286,8 +7408,13 @@ template<int start_offset>
|
| void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
|
| int object_size,
|
| ObjectVisitor* v) {
|
| - v->VisitPointers(HeapObject::RawField(obj, start_offset),
|
| - HeapObject::RawField(obj, object_size));
|
| + if (!FLAG_unbox_double_fields ||
|
| + obj->map()->layout_descriptor()->IsFastPointerLayout()) {
|
| + v->VisitPointers(HeapObject::RawField(obj, start_offset),
|
| + HeapObject::RawField(obj, object_size));
|
| + } else {
|
| + IterateBodyUsingLayoutDescriptor(obj, start_offset, object_size, v);
|
| + }
|
| }
|
|
|
|
|
|
|