Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(908)

Unified Diff: src/objects.h

Issue 391693002: In-object double fields unboxing (for 64-bit only). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressing comments Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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_

Powered by Google App Engine
This is Rietveld 408576698