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

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: Created 6 years, 5 months 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 d742b237c52b6f510f73c8ebda3654732c53d981..d2080689d5a2fb9d545d5ee0f2e3b11e3ff7c4a5 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -881,6 +881,7 @@ class ElementsAccessor;
class FixedArrayBase;
class GlobalObject;
class ObjectVisitor;
+class LayoutDescriptor;
class LookupIterator;
class StringStream;
// We cannot just say "class HeapType;" if it is created from a template... =8-?
@@ -905,112 +906,113 @@ template <class C> inline bool Is(Object* obj);
#endif
-#define OBJECT_TYPE_LIST(V) \
- V(Smi) \
- V(HeapObject) \
- V(Number) \
-
-#define HEAP_OBJECT_TYPE_LIST(V) \
- V(HeapNumber) \
- V(MutableHeapNumber) \
- V(Name) \
- V(UniqueName) \
- V(String) \
- V(SeqString) \
- V(ExternalString) \
- V(ConsString) \
- V(SlicedString) \
- V(ExternalTwoByteString) \
- V(ExternalAsciiString) \
- V(SeqTwoByteString) \
- V(SeqOneByteString) \
- V(InternalizedString) \
- V(Symbol) \
- \
- V(ExternalArray) \
- V(ExternalInt8Array) \
- V(ExternalUint8Array) \
- V(ExternalInt16Array) \
- V(ExternalUint16Array) \
- V(ExternalInt32Array) \
- V(ExternalUint32Array) \
- V(ExternalFloat32Array) \
- V(ExternalFloat64Array) \
- V(ExternalUint8ClampedArray) \
- V(FixedTypedArrayBase) \
- V(FixedUint8Array) \
- V(FixedInt8Array) \
- V(FixedUint16Array) \
- V(FixedInt16Array) \
- V(FixedUint32Array) \
- V(FixedInt32Array) \
- V(FixedFloat32Array) \
- V(FixedFloat64Array) \
- V(FixedUint8ClampedArray) \
- V(ByteArray) \
- V(FreeSpace) \
- V(JSReceiver) \
- V(JSObject) \
- V(JSContextExtensionObject) \
- V(JSGeneratorObject) \
- V(JSModule) \
- V(Map) \
- V(DescriptorArray) \
- V(TransitionArray) \
- V(DeoptimizationInputData) \
- V(DeoptimizationOutputData) \
- V(DependentCode) \
- V(FixedArray) \
- V(FixedDoubleArray) \
- V(ConstantPoolArray) \
- V(Context) \
- V(NativeContext) \
- V(ScopeInfo) \
- V(JSFunction) \
- V(Code) \
- V(Oddball) \
- V(SharedFunctionInfo) \
- V(JSValue) \
- V(JSDate) \
- V(JSMessageObject) \
- V(StringWrapper) \
- V(Foreign) \
- V(Boolean) \
- V(JSArray) \
- V(JSArrayBuffer) \
- V(JSArrayBufferView) \
- V(JSTypedArray) \
- V(JSDataView) \
- V(JSProxy) \
- V(JSFunctionProxy) \
- V(JSSet) \
- V(JSMap) \
- V(JSSetIterator) \
- V(JSMapIterator) \
- V(JSWeakCollection) \
- V(JSWeakMap) \
- V(JSWeakSet) \
- V(JSRegExp) \
- V(HashTable) \
- V(Dictionary) \
- V(StringTable) \
- V(JSFunctionResultCache) \
- V(NormalizedMapCache) \
- V(CompilationCacheTable) \
- V(CodeCacheHashTable) \
- V(PolymorphicCodeCacheHashTable) \
- V(MapCache) \
- V(Primitive) \
- V(GlobalObject) \
- V(JSGlobalObject) \
- V(JSBuiltinsObject) \
- V(JSGlobalProxy) \
- V(UndetectableObject) \
- V(AccessCheckNeeded) \
- V(Cell) \
- V(PropertyCell) \
- V(ObjectHashTable) \
- V(WeakHashTable) \
+#define OBJECT_TYPE_LIST(V) \
+ V(Smi) \
+ V(HeapObject) \
+ V(Number)
+
+#define HEAP_OBJECT_TYPE_LIST(V) \
+ V(HeapNumber) \
+ V(MutableHeapNumber) \
+ V(Name) \
+ V(UniqueName) \
+ V(String) \
+ V(SeqString) \
+ V(ExternalString) \
+ V(ConsString) \
+ V(SlicedString) \
+ V(ExternalTwoByteString) \
+ V(ExternalAsciiString) \
+ V(SeqTwoByteString) \
+ V(SeqOneByteString) \
+ V(InternalizedString) \
+ V(Symbol) \
+ \
+ V(ExternalArray) \
+ V(ExternalInt8Array) \
+ V(ExternalUint8Array) \
+ V(ExternalInt16Array) \
+ V(ExternalUint16Array) \
+ V(ExternalInt32Array) \
+ V(ExternalUint32Array) \
+ V(ExternalFloat32Array) \
+ V(ExternalFloat64Array) \
+ V(ExternalUint8ClampedArray) \
+ V(FixedTypedArrayBase) \
+ V(FixedUint8Array) \
+ V(FixedInt8Array) \
+ V(FixedUint16Array) \
+ V(FixedInt16Array) \
+ V(FixedUint32Array) \
+ V(FixedInt32Array) \
+ V(FixedFloat32Array) \
+ V(FixedFloat64Array) \
+ V(FixedUint8ClampedArray) \
+ V(ByteArray) \
+ V(FreeSpace) \
+ V(JSReceiver) \
+ V(JSObject) \
+ V(JSContextExtensionObject) \
+ V(JSGeneratorObject) \
+ V(JSModule) \
+ V(Map) \
+ V(DescriptorArray) \
+ V(LayoutDescriptor) \
+ V(TransitionArray) \
+ V(DeoptimizationInputData) \
+ V(DeoptimizationOutputData) \
+ V(DependentCode) \
+ V(FixedArray) \
+ V(FixedDoubleArray) \
+ V(ConstantPoolArray) \
+ V(Context) \
+ V(NativeContext) \
+ V(ScopeInfo) \
+ V(JSFunction) \
+ V(Code) \
+ V(Oddball) \
+ V(SharedFunctionInfo) \
+ V(JSValue) \
+ V(JSDate) \
+ V(JSMessageObject) \
+ V(StringWrapper) \
+ V(Foreign) \
+ V(Boolean) \
+ V(JSArray) \
+ V(JSArrayBuffer) \
+ V(JSArrayBufferView) \
+ V(JSTypedArray) \
+ V(JSDataView) \
+ V(JSProxy) \
+ V(JSFunctionProxy) \
+ V(JSSet) \
+ V(JSMap) \
+ V(JSSetIterator) \
+ V(JSMapIterator) \
+ V(JSWeakCollection) \
+ V(JSWeakMap) \
+ V(JSWeakSet) \
+ V(JSRegExp) \
+ V(HashTable) \
+ V(Dictionary) \
+ V(StringTable) \
+ V(JSFunctionResultCache) \
+ V(NormalizedMapCache) \
+ V(CompilationCacheTable) \
+ V(CodeCacheHashTable) \
+ V(PolymorphicCodeCacheHashTable) \
+ V(MapCache) \
+ V(Primitive) \
+ V(GlobalObject) \
+ V(JSGlobalObject) \
+ V(JSBuiltinsObject) \
+ V(JSGlobalProxy) \
+ V(UndetectableObject) \
+ V(AccessCheckNeeded) \
+ V(Cell) \
+ V(PropertyCell) \
+ V(ObjectHashTable) \
+ V(WeakHashTable) \
V(OrderedHashTable)
@@ -2470,8 +2472,13 @@ class JSObject: public JSReceiver {
Representation representation,
FieldIndex index);
inline Object* RawFastPropertyAt(FieldIndex index);
+ static inline Handle<Object> RawFastBoxedPropertyAt(Handle<JSObject> object,
+ FieldIndex index);
+ inline double RawFastDoublePropertyAt(FieldIndex index);
+ inline void FastPropertyAtPut(Map* map, FieldIndex index, Object* value);
inline void FastPropertyAtPut(FieldIndex index, Object* value);
void WriteToField(int descriptor, Object* value);
+ inline void FastDoublePropertyAtPut(FieldIndex index, double value);
// Access to in object properties.
inline int GetInObjectPropertyOffset(int index);
@@ -3413,6 +3420,10 @@ class DescriptorArray: public FixedArray {
inline void SetNumberOfDescriptors(int number_of_descriptors);
inline int number_of_entries() { return number_of_descriptors(); }
+ inline Object* cached_layout_descriptor();
+ inline void set_cached_layout_descriptor(LayoutDescriptor* cached);
+ inline void drop_cached_layout_descriptor();
+
bool HasEnumCache() {
return !IsEmpty() && !get(kEnumCacheIndex)->IsSmi();
}
@@ -3519,8 +3530,15 @@ class DescriptorArray: public FixedArray {
static const int kNotFound = -1;
static const int kDescriptorLengthIndex = 0;
+#if V8_DOUBLE_FIELDS_UNBOXING
+ static const int kLayoutDescriptorCacheIndex = 1;
+ static const int kEnumCacheIndex = 2;
+ static const int kFirstIndex = 3;
+#else
+ static const int kLayoutDescriptorCacheIndex = -1;
static const int kEnumCacheIndex = 1;
static const int kFirstIndex = 2;
+#endif
// The length of the "bridge" to the enum cache.
static const int kEnumCacheBridgeLength = 2;
@@ -3529,7 +3547,14 @@ class DescriptorArray: public FixedArray {
// Layout description.
static const int kDescriptorLengthOffset = FixedArray::kHeaderSize;
+#if V8_DOUBLE_FIELDS_UNBOXING
+ static const int kLayoutDescriptorOffset =
+ kDescriptorLengthOffset + kPointerSize;
+ static const int kEnumCacheOffset = kLayoutDescriptorOffset + kPointerSize;
+#else
+ static const int kLayoutDescriptorOffset = 1; // Must not be used.
static const int kEnumCacheOffset = kDescriptorLengthOffset + kPointerSize;
+#endif
static const int kFirstOffset = kEnumCacheOffset + kPointerSize;
// Layout description for the bridge array.
@@ -3616,9 +3641,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,
@@ -5277,6 +5300,60 @@ 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.
+class LayoutDescriptor : public FixedTypedArray<Uint32ArrayTraits> {
+ public:
+ INLINE(MUST_USE_RESULT LayoutDescriptor* SetTagged(int field_index,
+ bool tagged));
+ INLINE(bool IsTagged(int field_index));
+
+ // Returns true if this is a layout of the object having only tagged fields.
+ INLINE(bool IsFastPointerLayout());
+
+ DECLARE_CAST(LayoutDescriptor)
+ INLINE(static LayoutDescriptor* cast_gc_safe(Object* object));
+
+ // Builds layout descriptor by given descriptors array.
+ static Handle<LayoutDescriptor> New(Handle<DescriptorArray> descriptors);
+
+ // Layout descriptor that corresponds to an object all fields of which are
+ // tagged (FastPointerLayout).
+ INLINE(static LayoutDescriptor* FastPointerLayout());
+
+ // If the descriptor has fixed array form then this method tries to convert
+ // make an optimized descriptor which has a smi form if particular |map|
+ // refers only to a small part of the layout.
+ // Otherwise |this| is returned.
+ INLINE(LayoutDescriptor* OptimizeFor(Map* map));
+
+#ifdef DEBUG
+ // Check that this layout descriptor corresponds to given map.
+ bool IsConsistentWithMap(Map* map);
+#endif
+
+#ifdef OBJECT_PRINT
+ void Print(OStream& os); // NOLINT
+#endif
+
+ private:
+ static const int kNumberOfBits = 32;
+
+ INLINE(bool IsSlowLayout());
+
+ INLINE(static Handle<LayoutDescriptor> New(Isolate* isolate, int length));
+ INLINE(static LayoutDescriptor* FromSmi(Smi* smi));
+
+ INLINE(void GetIndexes(int field_index, int* layout_word_index,
+ uint32_t* layout_mask));
+};
+
// 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
@@ -6368,7 +6445,17 @@ 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();
+
+ inline static void RebuildLayoutDescriptor(Handle<Map> map);
Toon Verwaest 2014/07/29 15:02:09 Avoid having a Rebuild method. Just make sure that
+ inline void InitializeDescriptors(DescriptorArray* descriptors,
Toon Verwaest 2014/07/29 15:02:09 UpdateDescriptors / SetDescriptors
Igor Sheludko 2014/10/30 14:23:44 Done.
+ LayoutDescriptor* layout_descriptor);
+ inline void InitializeOwnDescriptors(DescriptorArray* descriptors,
Toon Verwaest 2014/07/29 15:02:09 InitializeDescriptors
Igor Sheludko 2014/10/30 14:23:44 Done.
+ LayoutDescriptor* layout_descriptor);
// [stub cache]: contains stubs compiled for this map.
DECL_ACCESSORS(code_cache, Object)
@@ -6678,7 +6765,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;
@@ -6756,6 +6849,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 Handle<TransitionArray> SetElementsTransitionMap(
Handle<Map> map, Handle<Map> transitioned_map);
@@ -6806,7 +6902,8 @@ class Map: public HeapObject {
void ZapTransitions();
void DeprecateTransitionTree();
- void DeprecateTarget(Name* key, DescriptorArray* new_descriptors);
+ void DeprecateTarget(Handle<Name> key,
+ Handle<DescriptorArray> new_descriptors);
Map* FindLastMatchMap(int verbatim, int length, DescriptorArray* descriptors);
@@ -11232,6 +11329,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