Chromium Code Reviews| Index: src/objects-inl.h |
| diff --git a/src/objects-inl.h b/src/objects-inl.h |
| index c00ecddb565afc5529e44a840c594e9dcf59dfa4..685f1d959056c4a364712e0ea95a39aa00a986b5 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() && \ |
| @@ -704,6 +713,11 @@ bool Object::IsDescriptorArray() const { |
| } |
| +bool Object::IsLayoutDescriptor() const { |
| + return IsSmi() || IsFixedTypedArrayBase(); |
| +} |
| + |
| + |
| bool Object::IsTransitionArray() const { |
| return IsFixedArray(); |
| } |
| @@ -2062,10 +2076,25 @@ void JSObject::SetInternalField(int index, Smi* value) { |
| } |
| +bool JSObject::IsUnboxedDoubleField(FieldIndex index) { |
| + if (!FLAG_unbox_double_fields) return false; |
| + if (index.is_hidden_field() || !index.is_inobject()) return false; |
| + return !map()->layout_descriptor()->IsTagged(index.property_index()); |
|
Hannes Payer (out of office)
2014/11/06 12:29:46
You could call IsUnboxedDoubleFrield from map.
Igor Sheludko
2014/11/07 08:03:52
I made two versions intentionally, to postpone cal
Hannes Payer (out of office)
2014/11/10 15:26:08
You are already calling map here. You could call m
Igor Sheludko
2014/11/10 15:43:54
Ok, lets make it look cleaner. Done.
|
| +} |
| + |
| + |
| +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 { |
| @@ -2074,7 +2103,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); |
| @@ -2085,6 +2120,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); |
| } |
| @@ -3082,8 +3132,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()); |
| } |
| @@ -3258,6 +3307,7 @@ CAST_ACCESSOR(JSTypedArray) |
| CAST_ACCESSOR(JSValue) |
| CAST_ACCESSOR(JSWeakMap) |
| CAST_ACCESSOR(JSWeakSet) |
| +CAST_ACCESSOR(LayoutDescriptor) |
| CAST_ACCESSOR(Map) |
| CAST_ACCESSOR(MapCache) |
| CAST_ACCESSOR(Name) |
| @@ -5141,14 +5191,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) { |
| @@ -5164,12 +5241,27 @@ uint32_t Map::bit_field3() { |
| } |
| +Handle<LayoutDescriptor> Map::GetLayoutDescriptor() { |
| + LayoutDescriptor* layout_desc = FLAG_unbox_double_fields |
| + ? layout_descriptor() |
| + : LayoutDescriptor::FastPointerLayout(); |
| + return handle(layout_desc, GetIsolate()); |
| +} |
| + |
| + |
| 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 |
| } |
| @@ -7201,12 +7293,36 @@ void ExternalTwoByteString::ExternalTwoByteStringIterateBody() { |
| } |
| +static 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); |
| + } |
| } |
| @@ -7214,8 +7330,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); |
| + } |
| } |