]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - dfg/DFGAbstractHeap.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / dfg / DFGAbstractHeap.h
index 338c99e31dd5cfcfd3f48fd1a26416c2295dd5bf..4dafbc1cbc0e8962ed3c839faa47da4e053c244c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 namespace JSC { namespace DFG {
 
-// Implements a three-level type hierarchy:
+// Implements a four-level type hierarchy:
 // - World is the supertype of all of the things.
-// - Kind with TOP payload is the direct subtype of World.
-// - Kind with non-TOP payload is the direct subtype of its corresponding TOP Kind.
+// - Stack with a TOP payload is a direct subtype of World
+// - Stack with a non-TOP payload is a direct subtype of Stack with a TOP payload.
+// - Heap is a direct subtype of World.
+// - Any other kind with TOP payload is the direct subtype of Heap.
+// - Any other kind with non-TOP payload is the direct subtype of the same kind with a TOP payload.
 
 #define FOR_EACH_ABSTRACT_HEAP_KIND(macro) \
     macro(InvalidAbstractHeap) \
     macro(World) \
-    macro(Arguments_numArguments) \
-    macro(Arguments_overrideLength) \
-    macro(Arguments_registers) \
-    macro(Arguments_slowArguments) \
-    macro(ArrayBuffer_data) \
-    macro(Butterfly_arrayBuffer) \
+    macro(Stack) \
+    macro(Heap) \
     macro(Butterfly_publicLength) \
     macro(Butterfly_vectorLength) \
-    macro(JSArrayBufferView_length) \
-    macro(JSArrayBufferView_mode) \
-    macro(JSArrayBufferView_vector) \
+    macro(GetterSetter_getter) \
+    macro(GetterSetter_setter) \
     macro(JSCell_structureID) \
     macro(JSCell_indexingType) \
     macro(JSCell_typeInfoFlags) \
     macro(JSCell_typeInfoType) \
-    macro(JSFunction_executable) \
-    macro(JSFunction_scopeChain) \
     macro(JSObject_butterfly) \
-    macro(JSVariableObject_registers) \
+    macro(JSPropertyNameEnumerator_cachedPropertyNames) \
     macro(NamedProperties) \
     macro(IndexedInt32Properties) \
     macro(IndexedDoubleProperties) \
     macro(IndexedContiguousProperties) \
+    macro(IndexedArrayStorageProperties) \
     macro(ArrayStorageProperties) \
-    macro(Variables) \
+    macro(DirectArgumentsProperties) \
+    macro(ScopeProperties) \
     macro(TypedArrayProperties) \
-    macro(GCState) \
-    macro(BarrierState) \
+    macro(HeapObjectCount) /* Used to reflect the fact that some allocations reveal object identity */\
     macro(RegExpState) \
     macro(InternalState) \
     macro(Absolute) \
     /* Use this for writes only, to indicate that this may fire watchpoints. Usually this is never directly written but instead we test to see if a node clobbers this; it just so happens that you have to write world to clobber it. */\
     macro(Watchpoint_fire) \
-    /* Use this for reads only, just to indicate that if the world got clobbered, then this operation will not work. */\
+    /* Use these for reads only, just to indicate that if the world got clobbered, then this operation will not work. */\
     macro(MiscFields) \
     /* Use this for writes only, just to indicate that hoisting the node is invalid. This works because we don't hoist anything that has any side effects at all. */\
     macro(SideState)
@@ -134,6 +131,11 @@ public:
             return m_value;
         }
         
+        int32_t value32() const
+        {
+            return static_cast<int32_t>(value());
+        }
+        
         bool operator==(const Payload& other) const
         {
             return m_isTop == other.m_isTop
@@ -188,7 +190,7 @@ public:
     
     AbstractHeap(AbstractHeapKind kind, Payload payload)
     {
-        ASSERT(kind != InvalidAbstractHeap && kind != World);
+        ASSERT(kind != InvalidAbstractHeap && kind != World && kind != Heap && kind != SideState);
         m_value = encode(kind, payload);
     }
     
@@ -206,32 +208,49 @@ public:
         return payloadImpl();
     }
     
-    bool isDisjoint(const AbstractHeap& other)
+    AbstractHeap supertype() const
     {
         ASSERT(kind() != InvalidAbstractHeap);
-        ASSERT(other.kind() != InvalidAbstractHeap);
-        if (kind() == World)
-            return false;
-        if (other.kind() == World)
-            return false;
-        if (kind() != other.kind())
-            return true;
-        return payload().isDisjoint(other.payload());
+        switch (kind()) {
+        case World:
+            return AbstractHeap();
+        case Heap:
+        case SideState:
+            return World;
+        default:
+            if (payload().isTop()) {
+                if (kind() == Stack)
+                    return World;
+                return Heap;
+            }
+            return AbstractHeap(kind());
+        }
     }
     
-    bool overlaps(const AbstractHeap& other)
+    bool isStrictSubtypeOf(const AbstractHeap& other) const
     {
-        return !isDisjoint(other);
+        AbstractHeap current = *this;
+        while (current.kind() != World) {
+            current = current.supertype();
+            if (current == other)
+                return true;
+        }
+        return false;
     }
     
-    AbstractHeap supertype() const
+    bool isSubtypeOf(const AbstractHeap& other) const
     {
-        ASSERT(kind() != InvalidAbstractHeap);
-        if (kind() == World)
-            return AbstractHeap();
-        if (payload().isTop())
-            return World;
-        return AbstractHeap(kind());
+        return *this == other || isStrictSubtypeOf(other);
+    }
+    
+    bool overlaps(const AbstractHeap& other) const
+    {
+        return *this == other || isStrictSubtypeOf(other) || other.isStrictSubtypeOf(*this);
+    }
+    
+    bool isDisjoint(const AbstractHeap& other) const
+    {
+        return !overlaps(other);
     }
     
     unsigned hash() const