| Index: src/objects.h
|
| diff --git a/src/objects.h b/src/objects.h
|
| index fbe06c70286654161b6de8b58c639e3f2613cb31..523eac7a497648511e8deb1e21b8029cd9cc63fc 100644
|
| --- a/src/objects.h
|
| +++ b/src/objects.h
|
| @@ -857,6 +857,7 @@ class ElementsAccessor;
|
| class FixedArrayBase;
|
| class GlobalObject;
|
| class ObjectVisitor;
|
| +class LayoutDescriptor;
|
| class LookupIterator;
|
| class StringStream;
|
| class TypeFeedbackVector;
|
| @@ -932,6 +933,7 @@ template <class C> inline bool Is(Object* obj);
|
| V(JSContextExtensionObject) \
|
| V(JSGeneratorObject) \
|
| V(JSModule) \
|
| + V(LayoutDescriptor) \
|
| V(Map) \
|
| V(DescriptorArray) \
|
| V(TransitionArray) \
|
| @@ -2059,12 +2061,18 @@ class JSObject: public JSReceiver {
|
| static void MigrateSlowToFast(Handle<JSObject> object,
|
| int unused_property_fields);
|
|
|
| + inline bool IsUnboxedDoubleField(FieldIndex index);
|
| +
|
| // Access fast-case object properties at index.
|
| static Handle<Object> FastPropertyAt(Handle<JSObject> object,
|
| Representation representation,
|
| FieldIndex index);
|
| inline Object* RawFastPropertyAt(FieldIndex index);
|
| + inline double RawFastDoublePropertyAt(FieldIndex index);
|
| +
|
| inline void FastPropertyAtPut(FieldIndex index, Object* value);
|
| + inline void RawFastPropertyAtPut(FieldIndex index, Object* value);
|
| + inline void RawFastDoublePropertyAtPut(FieldIndex index, double value);
|
| void WriteToField(int descriptor, Object* value);
|
|
|
| // Access to in object properties.
|
| @@ -3128,9 +3136,7 @@ class DescriptorArray: public FixedArray {
|
|
|
| // Transfer a complete descriptor from the src descriptor array to this
|
| // descriptor array.
|
| - void CopyFrom(int index,
|
| - DescriptorArray* src,
|
| - const WhitenessWitness&);
|
| + void CopyFrom(int index, DescriptorArray* src, const WhitenessWitness&);
|
|
|
| inline void Set(int descriptor_number,
|
| Descriptor* desc,
|
| @@ -4813,6 +4819,91 @@ TYPED_ARRAYS(FIXED_TYPED_ARRAY_TRAITS)
|
|
|
| #undef FIXED_TYPED_ARRAY_TRAITS
|
|
|
| +
|
| +// LayoutDescriptor is a bit vector defining which fields contain non-tagged
|
| +// values. It could either be a fixed typed array (slow form) or a Smi
|
| +// if the length fits (fast form).
|
| +// Each bit in the layout represents a FIELD. The bits are referenced by
|
| +// field_index which is a field number. If the bit is set then corresponding
|
| +// field contains non tagged value and therefore must be skipped by GC.
|
| +// Otherwise the field is considered tagged. If the queried bit lays "outside"
|
| +// of the descriptor then the field is also considered tagged.
|
| +// Once a layout descriptor is created it is allowed only to append properties
|
| +// to it.
|
| +class LayoutDescriptor : public FixedTypedArray<Uint32ArrayTraits> {
|
| + public:
|
| + V8_INLINE bool IsTagged(int field_index);
|
| +
|
| + // Returns true if this is a layout of the object having only tagged fields.
|
| + V8_INLINE bool IsFastPointerLayout();
|
| +
|
| + // Returns true if the layout descriptor is in non-Smi form.
|
| + V8_INLINE bool IsSlowLayout();
|
| +
|
| + DECLARE_CAST(LayoutDescriptor)
|
| + V8_INLINE static LayoutDescriptor* cast_gc_safe(Object* object);
|
| +
|
| + // Builds layout descriptor optimized for given |map| by |num_descriptors|
|
| + // elements of given descriptors array. The |map|'s descriptors could be
|
| + // different.
|
| + static Handle<LayoutDescriptor> New(Handle<Map> map,
|
| + Handle<DescriptorArray> descriptors,
|
| + int num_descriptors);
|
| +
|
| + // Creates new layout descriptor by appending property with |details| to
|
| + // |map|'s layout descriptor.
|
| + static Handle<LayoutDescriptor> Append(Handle<Map> map,
|
| + PropertyDetails details);
|
| +
|
| + // Creates new layout descriptor by appending property with |details| to
|
| + // |map|'s layout descriptor and if it is still fast then returns it.
|
| + // Otherwise the |full_layout_descriptor| is returned.
|
| + static Handle<LayoutDescriptor> AppendIfFastOrUseFull(
|
| + Handle<Map> map, PropertyDetails details,
|
| + Handle<LayoutDescriptor> full_layout_descriptor);
|
| +
|
| + // Layout descriptor that corresponds to an object all fields of which are
|
| + // tagged (FastPointerLayout).
|
| + V8_INLINE static LayoutDescriptor* FastPointerLayout();
|
| +
|
| +#ifdef DEBUG
|
| + // Check that this layout descriptor corresponds to given map.
|
| + bool IsConsistentWithMap(Map* map);
|
| +#endif
|
| +
|
| +#ifdef OBJECT_PRINT
|
| + // For our gdb macros, we should perhaps change these in the future.
|
| + void Print();
|
| +
|
| + void Print(std::ostream& os); // NOLINT
|
| +#endif
|
| +
|
| + private:
|
| + static const int kNumberOfBits = 32;
|
| +
|
| + V8_INLINE static Handle<LayoutDescriptor> New(Isolate* isolate, int length);
|
| + V8_INLINE static LayoutDescriptor* FromSmi(Smi* smi);
|
| +
|
| + V8_INLINE static bool InobjectUnboxedField(int inobject_properties,
|
| + PropertyDetails details);
|
| +
|
| + static Handle<LayoutDescriptor> EnsureCapacity(
|
| + Isolate* isolate, Handle<LayoutDescriptor> layout_descriptor,
|
| + int new_capacity);
|
| +
|
| + // Returns false if requested field_index is out of bounds.
|
| + V8_INLINE bool GetIndexes(int field_index, int* layout_word_index,
|
| + uint32_t* layout_mask);
|
| +
|
| + V8_INLINE MUST_USE_RESULT LayoutDescriptor* SetTagged(int field_index,
|
| + bool tagged);
|
| + // Capacity of layout descriptors in bits.
|
| + V8_INLINE int capacity();
|
| +
|
| + friend class TestAccessor;
|
| +};
|
| +
|
| +
|
| // DeoptimizationInputData is a fixed array used to hold the deoptimization
|
| // data for code generated by the Hydrogen/Lithium compiler. It also
|
| // contains information about functions that were inlined. If N different
|
| @@ -5903,7 +5994,19 @@ class Map: public HeapObject {
|
|
|
| // [instance descriptors]: describes the object.
|
| DECL_ACCESSORS(instance_descriptors, DescriptorArray)
|
| - inline void InitializeDescriptors(DescriptorArray* descriptors);
|
| +
|
| + // [layout descriptor]: describes the object layout.
|
| + DECL_ACCESSORS(layout_descriptor, LayoutDescriptor)
|
| + // |layout descriptor| accessor which can be used from GC.
|
| + inline LayoutDescriptor* layout_descriptor_gc_safe();
|
| +
|
| + // |layout descriptor| accessor that returns a handle.
|
| + inline Handle<LayoutDescriptor> GetLayoutDescriptor();
|
| +
|
| + inline void UpdateDescriptors(DescriptorArray* descriptors,
|
| + LayoutDescriptor* layout_descriptor);
|
| + inline void InitializeDescriptors(DescriptorArray* descriptors,
|
| + LayoutDescriptor* layout_descriptor);
|
|
|
| // [stub cache]: contains stubs compiled for this map.
|
| DECL_ACCESSORS(code_cache, Object)
|
| @@ -6231,7 +6334,13 @@ class Map: public HeapObject {
|
| kConstructorOffset + kPointerSize;
|
| static const int kDescriptorsOffset =
|
| kTransitionsOrBackPointerOffset + kPointerSize;
|
| +#if V8_DOUBLE_FIELDS_UNBOXING
|
| + static const int kLayoutDecriptorOffset = kDescriptorsOffset + kPointerSize;
|
| + static const int kCodeCacheOffset = kLayoutDecriptorOffset + kPointerSize;
|
| +#else
|
| + static const int kLayoutDecriptorOffset = 1; // Must not be ever accessed.
|
| static const int kCodeCacheOffset = kDescriptorsOffset + kPointerSize;
|
| +#endif
|
| static const int kDependentCodeOffset = kCodeCacheOffset + kPointerSize;
|
| static const int kSize = kDependentCodeOffset + kPointerSize;
|
|
|
| @@ -6309,6 +6418,9 @@ class Map: public HeapObject {
|
| // The "shared" flags of both this map and |other| are ignored.
|
| bool EquivalentToForNormalization(Map* other, PropertyNormalizationMode mode);
|
|
|
| + // Returns true if given field is unboxed double.
|
| + inline bool IsUnboxedDoubleField(FieldIndex index);
|
| +
|
| private:
|
| static void ConnectElementsTransition(Handle<Map> parent, Handle<Map> child);
|
| static void ConnectTransition(Handle<Map> parent, Handle<Map> child,
|
| @@ -6320,16 +6432,14 @@ class Map: public HeapObject {
|
| Handle<DescriptorArray> descriptors,
|
| Descriptor* descriptor);
|
| static Handle<Map> CopyInstallDescriptors(
|
| - Handle<Map> map,
|
| - int new_descriptor,
|
| - Handle<DescriptorArray> descriptors);
|
| + Handle<Map> map, int new_descriptor, Handle<DescriptorArray> descriptors,
|
| + Handle<LayoutDescriptor> layout_descriptor);
|
| static Handle<Map> CopyAddDescriptor(Handle<Map> map,
|
| Descriptor* descriptor,
|
| TransitionFlag flag);
|
| static Handle<Map> CopyReplaceDescriptors(
|
| - Handle<Map> map,
|
| - Handle<DescriptorArray> descriptors,
|
| - TransitionFlag flag,
|
| + Handle<Map> map, Handle<DescriptorArray> descriptors,
|
| + Handle<LayoutDescriptor> layout_descriptor, TransitionFlag flag,
|
| MaybeHandle<Name> maybe_name,
|
| SimpleTransitionFlag simple_flag = FULL_TRANSITION);
|
| static Handle<Map> CopyReplaceDescriptor(Handle<Map> map,
|
| @@ -6359,7 +6469,9 @@ class Map: public HeapObject {
|
| void ZapTransitions();
|
|
|
| void DeprecateTransitionTree();
|
| - void DeprecateTarget(Name* key, DescriptorArray* new_descriptors);
|
| + void DeprecateTarget(Handle<Name> key,
|
| + Handle<DescriptorArray> new_descriptors,
|
| + Handle<LayoutDescriptor> new_layout_descriptor);
|
|
|
| Map* FindLastMatchMap(int verbatim, int length, DescriptorArray* descriptors);
|
|
|
| @@ -6390,6 +6502,7 @@ class Map: public HeapObject {
|
| static const int kFastPropertiesSoftLimit = 12;
|
| static const int kMaxFastProperties = 128;
|
|
|
| + friend class TestAccessor;
|
| DISALLOW_IMPLICIT_CONSTRUCTORS(Map);
|
| };
|
|
|
| @@ -10912,6 +11025,22 @@ class BooleanBit : public AllStatic {
|
| }
|
| };
|
|
|
| +
|
| +// InobjectPropertiesHelper is a helper class for querying layout descriptor
|
| +// about whether the field at given offset is tagged or not.
|
| +class InobjectPropertiesHelper {
|
| + public:
|
| + inline explicit InobjectPropertiesHelper(Map* map);
|
| +
|
| + bool all_fields_tagged() { return all_fields_tagged_; }
|
| + inline bool IsTagged(int offset_in_bytes);
|
| +
|
| + private:
|
| + bool all_fields_tagged_;
|
| + int header_size_;
|
| + int inobject_properties_count_;
|
| + LayoutDescriptor* layout_descriptor_;
|
| +};
|
| } } // namespace v8::internal
|
|
|
| #endif // V8_OBJECTS_H_
|
|
|