bmalloc: Renamed LargeChunk => Chunk
[WebKit-https.git] / Source / bmalloc / bmalloc / LargeObject.h
index c63cc47..70d91b2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #define LargeObject_h
 
 #include "BeginTag.h"
+#include "Chunk.h"
 #include "EndTag.h"
-#include "LargeChunk.h"
 #include "Range.h"
 
 namespace bmalloc {
 
 class LargeObject {
 public:
-    static Range init(LargeChunk*);
-
     LargeObject();
     LargeObject(void*);
 
     enum DoNotValidateTag { DoNotValidate };
     LargeObject(DoNotValidateTag, void*);
     
+    operator bool() { return !!*this; }
     bool operator!() { return !m_object; }
 
     char* begin() const { return static_cast<char*>(m_object); }
+    char* end() const { return begin() + size(); }
     size_t size() const { return m_beginTag->size(); }
     Range range() const { return Range(m_object, size()); }
 
     void setFree(bool) const;
     bool isFree() const;
-    
-    bool hasPhysicalPages() const;
-    void setHasPhysicalPages(bool) const;
-    
-    bool isValidAndFree(size_t) const;
+
+    bool prevCanMerge() const;
+    bool nextCanMerge() const;
+
+    VMState vmState() const;
+    void setVMState(VMState) const;
+
+    bool isMarked() const;
+    void setMarked(bool) const;
+
+    bool isValidAndFree(VMState::HasPhysical, size_t) const;
 
     LargeObject merge() const;
     std::pair<LargeObject, LargeObject> split(size_t) const;
@@ -79,16 +85,16 @@ inline LargeObject::LargeObject()
 }
 
 inline LargeObject::LargeObject(void* object)
-    : m_beginTag(LargeChunk::beginTag(object))
-    , m_endTag(LargeChunk::endTag(object, m_beginTag->size()))
+    : m_beginTag(Chunk::beginTag(object))
+    , m_endTag(Chunk::endTag(object, m_beginTag->size()))
     , m_object(object)
 {
     validate();
 }
 
 inline LargeObject::LargeObject(DoNotValidateTag, void* object)
-    : m_beginTag(LargeChunk::beginTag(object))
-    , m_endTag(LargeChunk::endTag(object, m_beginTag->size()))
+    : m_beginTag(Chunk::beginTag(object))
+    , m_endTag(Chunk::endTag(object, m_beginTag->size()))
     , m_object(object)
 {
 }
@@ -113,20 +119,43 @@ inline bool LargeObject::isFree() const
     return m_beginTag->isFree();
 }
 
-inline bool LargeObject::hasPhysicalPages() const
+inline bool LargeObject::prevCanMerge() const
+{
+    return m_beginTag->prev()->isFree();
+}
+
+inline bool LargeObject::nextCanMerge() const
+{
+    return m_endTag->next()->isFree();
+}
+
+inline VMState LargeObject::vmState() const
+{
+    validate();
+    return m_beginTag->vmState();
+}
+
+inline void LargeObject::setVMState(VMState vmState) const
+{
+    validate();
+    m_beginTag->setVMState(vmState);
+    m_endTag->setVMState(vmState);
+}
+
+inline bool LargeObject::isMarked() const
 {
     validate();
-    return m_beginTag->hasPhysicalPages();
+    return m_beginTag->isMarked();
 }
 
-inline void LargeObject::setHasPhysicalPages(bool hasPhysicalPages) const
+inline void LargeObject::setMarked(bool isMarked) const
 {
     validate();
-    m_beginTag->setHasPhysicalPages(hasPhysicalPages);
-    m_endTag->setHasPhysicalPages(hasPhysicalPages);
+    m_beginTag->setMarked(isMarked);
+    m_endTag->setMarked(isMarked);
 }
 
-inline bool LargeObject::isValidAndFree(size_t expectedSize) const
+inline bool LargeObject::isValidAndFree(VMState::HasPhysical hasPhysical, size_t expectedSize) const
 {
     if (!m_beginTag->isFree())
         return false;
@@ -140,6 +169,9 @@ inline bool LargeObject::isValidAndFree(size_t expectedSize) const
     if (m_beginTag->compactBegin() != BoundaryTag::compactBegin(m_object))
         return false;
 
+    if (m_beginTag->vmState().hasPhysical() != static_cast<bool>(hasPhysical))
+        return false;
+
     return true;
 }
 
@@ -148,40 +180,38 @@ inline LargeObject LargeObject::merge() const
     validate();
     BASSERT(isFree());
 
-    bool hasPhysicalPages = m_beginTag->hasPhysicalPages();
-
     BeginTag* beginTag = m_beginTag;
     EndTag* endTag = m_endTag;
     Range range = this->range();
-    
+    VMState vmState = this->vmState();
+
     EndTag* prev = beginTag->prev();
     if (prev->isFree()) {
+        vmState.merge(prev->vmState());
         Range left(range.begin() - prev->size(), prev->size());
         range = Range(left.begin(), left.size() + range.size());
-        hasPhysicalPages &= prev->hasPhysicalPages();
 
         prev->clear();
         beginTag->clear();
 
-        beginTag = LargeChunk::beginTag(range.begin());
+        beginTag = Chunk::beginTag(range.begin());
     }
 
     BeginTag* next = endTag->next();
     if (next->isFree()) {
+        vmState.merge(next->vmState());
         Range right(range.end(), next->size());
         range = Range(range.begin(), range.size() + right.size());
 
-        hasPhysicalPages &= next->hasPhysicalPages();
-
         endTag->clear();
         next->clear();
 
-        endTag = LargeChunk::endTag(range.begin(), range.size());
+        endTag = Chunk::endTag(range.begin(), range.size());
     }
 
     beginTag->setRange(range);
     beginTag->setFree(true);
-    beginTag->setHasPhysicalPages(hasPhysicalPages);
+    beginTag->setVMState(vmState);
     endTag->init(beginTag);
 
     return LargeObject(beginTag, endTag, range.begin());
@@ -189,16 +219,15 @@ inline LargeObject LargeObject::merge() const
 
 inline std::pair<LargeObject, LargeObject> LargeObject::split(size_t size) const
 {
-    BASSERT(isFree());
-
+    BASSERT(size <= this->size());
     Range split(begin(), size);
     Range leftover = Range(split.end(), this->size() - size);
     BASSERT(leftover.size() >= largeMin);
 
     BeginTag* splitBeginTag = m_beginTag;
-    EndTag* splitEndTag = LargeChunk::endTag(split.begin(), size);
+    EndTag* splitEndTag = Chunk::endTag(split.begin(), size);
 
-    BeginTag* leftoverBeginTag = LargeChunk::beginTag(leftover.begin());
+    BeginTag* leftoverBeginTag = Chunk::beginTag(leftover.begin());
     EndTag* leftoverEndTag = m_endTag;
 
     splitBeginTag->setRange(split);
@@ -222,7 +251,8 @@ inline void LargeObject::validateSelf() const
 
     BASSERT(m_beginTag->size() == m_endTag->size());
     BASSERT(m_beginTag->isFree() == m_endTag->isFree());
-    BASSERT(m_beginTag->hasPhysicalPages() == m_endTag->hasPhysicalPages());
+    BASSERT(m_beginTag->vmState() == m_endTag->vmState());
+    BASSERT(m_beginTag->isMarked() == m_endTag->isMarked());
 }
 
 inline void LargeObject::validate() const
@@ -240,33 +270,6 @@ inline void LargeObject::validate() const
     }
 }
 
-inline Range LargeObject::init(LargeChunk* chunk)
-{
-    Range range(chunk->begin(), chunk->end() - chunk->begin());
-
-    BeginTag* beginTag = LargeChunk::beginTag(range.begin());
-    beginTag->setRange(range);
-    beginTag->setFree(true);
-    beginTag->setHasPhysicalPages(false);
-
-    EndTag* endTag = LargeChunk::endTag(range.begin(), range.size());
-    endTag->init(beginTag);
-
-    // Mark the left and right edges of our chunk as allocated. This naturally
-    // prevents merging logic from overflowing beyond our chunk, without requiring
-    // special-case checks.
-    
-    EndTag* leftSentinel = beginTag->prev();
-    BASSERT(leftSentinel >= static_cast<void*>(chunk));
-    leftSentinel->initSentinel();
-
-    BeginTag* rightSentinel = endTag->next();
-    BASSERT(rightSentinel < static_cast<void*>(range.begin()));
-    rightSentinel->initSentinel();
-    
-    return range;
-}
-
 } // namespace bmalloc
 
 #endif // LargeObject_h