1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "config.h"
6#include "platform/heap/Handle.h"
7
8namespace blink {
9
10bool WrapperPersistentRegion::removeIfNotLast(WrapperPersistentRegion** headPtr)
11{
12    ASSERT(!m_count);
13    // We are the last region in the list if both the region's m_prev and
14    // m_next are 0.
15    if (!m_prev && !m_next)
16        return false;
17    if (m_prev) {
18        m_prev->m_next = m_next;
19    } else {
20        ASSERT(*headPtr == this);
21        *headPtr = m_next;
22    }
23    if (m_next)
24        m_next->m_prev = m_prev;
25    m_prev = 0;
26    m_next = 0;
27    return true;
28}
29
30void WrapperPersistentRegion::insertHead(WrapperPersistentRegion** headPtr, WrapperPersistentRegion* newHead)
31{
32    ASSERT(headPtr);
33    WrapperPersistentRegion* oldHead = *headPtr;
34    if (oldHead) {
35        ASSERT(!oldHead->m_prev);
36        oldHead->m_prev = newHead;
37    }
38    newHead->m_prev = 0;
39    newHead->m_next = oldHead;
40    *headPtr = newHead;
41}
42
43WrapperPersistentRegion* WrapperPersistentRegion::removeHead(WrapperPersistentRegion** headPtr)
44{
45    // We only call this if there is at least one element in the list.
46    ASSERT(headPtr && *headPtr);
47    WrapperPersistentRegion* oldHead = *headPtr;
48    ASSERT(!oldHead->m_prev);
49    *headPtr = oldHead->m_next;
50    oldHead->m_next = 0;
51    ASSERT(!(*headPtr) || (*headPtr)->m_prev == oldHead);
52    if (*headPtr)
53        (*headPtr)->m_prev = 0;
54    return oldHead;
55}
56
57Address WrapperPersistentRegion::outOfLineAllocate(ThreadState* state, WrapperPersistentRegion** regionPtr)
58{
59    Address persistentSlot = 0;
60    // The caller has already tried allocating in the passed-in region, start
61    // from the next.
62    for (WrapperPersistentRegion* current = (*regionPtr)->m_next; current; current = current->m_next) {
63        persistentSlot = current->allocate();
64        if (persistentSlot) {
65            *regionPtr = current;
66            return persistentSlot;
67        }
68    }
69    ASSERT(!persistentSlot);
70    WrapperPersistentRegion* newRegion = state->takeWrapperPersistentRegion();
71    persistentSlot = newRegion->allocate();
72    *regionPtr = newRegion;
73    ASSERT(persistentSlot);
74    return persistentSlot;
75}
76
77}
78