/*
 * Copyright (C) 2016-2019 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#pragma once

#include "DestructionMode.h"

namespace JSC {

class CellContainer;
class Heap;
class PreciseAllocation;
class MarkedBlock;
class Subspace;
class VM;
struct CellAttributes;

#if COMPILER(GCC_COMPATIBLE)
ALWAYS_INLINE void ensureStillAliveHere(const void* pointer)
{
    asm volatile ("" : : "r"(pointer) : "memory");
}
#else
JS_EXPORT_PRIVATE void ensureStillAliveHere(const void*);
#endif

class HeapCell {
public:
    enum Kind : int8_t {
        JSCell,
        JSCellWithInteriorPointers,
        Auxiliary
    };
    
    HeapCell() { }
    
    // We're intentionally only zapping the bits for the structureID and leaving
    // the rest of the cell header bits intact for crash analysis uses.
    enum ZapReason : int8_t { Unspecified, Destruction, StopAllocating };
    void zap(ZapReason reason)
    {
        uint32_t* cellWords = bitwise_cast<uint32_t*>(this);
        cellWords[0] = 0;
        // Leaving cellWords[1] alone for crash analysis if needed.
        cellWords[2] = reason;
    }
    bool isZapped() const { return !*bitwise_cast<const uint32_t*>(this); }

    bool isLive();

    bool isPreciseAllocation() const;
    CellContainer cellContainer() const;
    MarkedBlock& markedBlock() const;
    PreciseAllocation& preciseAllocation() const;

    // If you want performance and you know that your cell is small, you can do this instead:
    // ASSERT(!cell->isPreciseAllocation());
    // cell->markedBlock().vm()
    // We currently only use this hack for callees to make CallFrame::vm() fast. It's not
    // recommended to use it for too many other things, since the large allocation cutoff is
    // a runtime option and its default value is small (400 bytes).
    Heap* heap() const;
    VM& vm() const;
    
    size_t cellSize() const;
    CellAttributes cellAttributes() const;
    DestructionMode destructionMode() const;
    Kind cellKind() const;
    Subspace* subspace() const;
    
    // Call use() after the last point where you need `this` pointer to be kept alive. You usually don't
    // need to use this, but it might be necessary if you're otherwise referring to an object's innards
    // but not the object itself.
    ALWAYS_INLINE void use() const
    {
        ensureStillAliveHere(this);
    }
};

inline bool isJSCellKind(HeapCell::Kind kind)
{
    return kind == HeapCell::JSCell || kind == HeapCell::JSCellWithInteriorPointers;
}

inline bool hasInteriorPointers(HeapCell::Kind kind)
{
    return kind == HeapCell::Auxiliary || kind == HeapCell::JSCellWithInteriorPointers;
}

} // namespace JSC

namespace WTF {

class PrintStream;

void printInternal(PrintStream&, JSC::HeapCell::Kind);

} // namespace WTF

