Changeset View
Changeset View
Standalone View
Standalone View
libraries/source/spidermonkey/include-win32-debug/js/TraceKind.h
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- | ||||
* vim: set ts=8 sts=4 et sw=4 tw=99: | * vim: set ts=8 sts=4 et sw=4 tw=99: | ||||
* This Source Code Form is subject to the terms of the Mozilla Public | * This Source Code Form is subject to the terms of the Mozilla Public | ||||
* License, v. 2.0. If a copy of the MPL was not distributed with this | * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||||
#ifndef js_TraceKind_h | #ifndef js_TraceKind_h | ||||
#define js_TraceKind_h | #define js_TraceKind_h | ||||
#include "mozilla/UniquePtr.h" | |||||
#include "js/TypeDecls.h" | #include "js/TypeDecls.h" | ||||
// Forward declarations of all the types a TraceKind can denote. | // Forward declarations of all the types a TraceKind can denote. | ||||
namespace js { | namespace js { | ||||
class BaseShape; | class BaseShape; | ||||
class LazyScript; | class LazyScript; | ||||
class ObjectGroup; | class ObjectGroup; | ||||
class Shape; | class Shape; | ||||
class Scope; | |||||
namespace jit { | namespace jit { | ||||
class JitCode; | class JitCode; | ||||
} // namespace jit | } // namespace jit | ||||
} // namespace js | } // namespace js | ||||
namespace JS { | namespace JS { | ||||
// When tracing a thing, the GC needs to know about the layout of the object it | // When tracing a thing, the GC needs to know about the layout of the object it | ||||
Show All 22 Lines | enum class TraceKind | ||||
ObjectGroup = 0x05, | ObjectGroup = 0x05, | ||||
// The kind associated with a nullptr. | // The kind associated with a nullptr. | ||||
Null = 0x06, | Null = 0x06, | ||||
// The following kinds do not have an exposed C++ idiom. | // The following kinds do not have an exposed C++ idiom. | ||||
BaseShape = 0x0F, | BaseShape = 0x0F, | ||||
JitCode = 0x1F, | JitCode = 0x1F, | ||||
LazyScript = 0x2F | LazyScript = 0x2F, | ||||
Scope = 0x3F | |||||
}; | }; | ||||
const static uintptr_t OutOfLineTraceKindMask = 0x07; | const static uintptr_t OutOfLineTraceKindMask = 0x07; | ||||
static_assert(uintptr_t(JS::TraceKind::BaseShape) & OutOfLineTraceKindMask, "mask bits are set"); | static_assert(uintptr_t(JS::TraceKind::BaseShape) & OutOfLineTraceKindMask, "mask bits are set"); | ||||
static_assert(uintptr_t(JS::TraceKind::JitCode) & OutOfLineTraceKindMask, "mask bits are set"); | static_assert(uintptr_t(JS::TraceKind::JitCode) & OutOfLineTraceKindMask, "mask bits are set"); | ||||
static_assert(uintptr_t(JS::TraceKind::LazyScript) & OutOfLineTraceKindMask, "mask bits are set"); | static_assert(uintptr_t(JS::TraceKind::LazyScript) & OutOfLineTraceKindMask, "mask bits are set"); | ||||
static_assert(uintptr_t(JS::TraceKind::Scope) & OutOfLineTraceKindMask, "mask bits are set"); | |||||
// When this header is imported inside SpiderMonkey, the class definitions are | |||||
// available and we can query those definitions to find the correct kind | |||||
// directly from the class hierarchy. | |||||
template <typename T> | |||||
struct MapTypeToTraceKind { | |||||
static const JS::TraceKind kind = T::TraceKind; | |||||
}; | |||||
// When this header is used outside SpiderMonkey, the class definitions are not | |||||
// available, so the following table containing all public GC types is used. | |||||
#define JS_FOR_EACH_TRACEKIND(D) \ | #define JS_FOR_EACH_TRACEKIND(D) \ | ||||
/* PrettyName TypeName AddToCCKind */ \ | /* PrettyName TypeName AddToCCKind */ \ | ||||
D(BaseShape, js::BaseShape, true) \ | D(BaseShape, js::BaseShape, true) \ | ||||
D(JitCode, js::jit::JitCode, true) \ | D(JitCode, js::jit::JitCode, true) \ | ||||
D(LazyScript, js::LazyScript, true) \ | D(LazyScript, js::LazyScript, true) \ | ||||
D(Scope, js::Scope, true) \ | |||||
D(Object, JSObject, true) \ | D(Object, JSObject, true) \ | ||||
D(ObjectGroup, js::ObjectGroup, true) \ | D(ObjectGroup, js::ObjectGroup, true) \ | ||||
D(Script, JSScript, true) \ | D(Script, JSScript, true) \ | ||||
D(Shape, js::Shape, true) \ | D(Shape, js::Shape, true) \ | ||||
D(String, JSString, false) \ | D(String, JSString, false) \ | ||||
D(Symbol, JS::Symbol, false) | D(Symbol, JS::Symbol, false) | ||||
// Map from base trace type to the trace kind. | // Map from all public types to their trace kind. | ||||
template <typename T> struct MapTypeToTraceKind {}; | |||||
#define JS_EXPAND_DEF(name, type, _) \ | #define JS_EXPAND_DEF(name, type, _) \ | ||||
template <> struct MapTypeToTraceKind<type> { \ | template <> struct MapTypeToTraceKind<type> { \ | ||||
static const JS::TraceKind kind = JS::TraceKind::name; \ | static const JS::TraceKind kind = JS::TraceKind::name; \ | ||||
}; | }; | ||||
JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF); | JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF); | ||||
#undef JS_EXPAND_DEF | #undef JS_EXPAND_DEF | ||||
// RootKind is closely related to TraceKind. Whereas TraceKind's indices are | |||||
// laid out for convenient embedding as a pointer tag, the indicies of RootKind | |||||
// are designed for use as array keys via EnumeratedArray. | |||||
enum class RootKind : int8_t | |||||
{ | |||||
// These map 1:1 with trace kinds. | |||||
#define EXPAND_ROOT_KIND(name, _0, _1) \ | |||||
name, | |||||
JS_FOR_EACH_TRACEKIND(EXPAND_ROOT_KIND) | |||||
#undef EXPAND_ROOT_KIND | |||||
// These tagged pointers are special-cased for performance. | |||||
Id, | |||||
Value, | |||||
// Everything else. | |||||
Traceable, | |||||
Limit | |||||
}; | |||||
// Most RootKind correspond directly to a trace kind. | |||||
template <TraceKind traceKind> struct MapTraceKindToRootKind {}; | |||||
#define JS_EXPAND_DEF(name, _0, _1) \ | |||||
template <> struct MapTraceKindToRootKind<JS::TraceKind::name> { \ | |||||
static const JS::RootKind kind = JS::RootKind::name; \ | |||||
}; | |||||
JS_FOR_EACH_TRACEKIND(JS_EXPAND_DEF) | |||||
#undef JS_EXPAND_DEF | |||||
// Specify the RootKind for all types. Value and jsid map to special cases; | |||||
// pointer types we can derive directly from the TraceKind; everything else | |||||
// should go in the Traceable list and use GCPolicy<T>::trace for tracing. | |||||
template <typename T> | |||||
struct MapTypeToRootKind { | |||||
static const JS::RootKind kind = JS::RootKind::Traceable; | |||||
}; | |||||
template <typename T> | |||||
struct MapTypeToRootKind<T*> { | |||||
static const JS::RootKind kind = | |||||
JS::MapTraceKindToRootKind<JS::MapTypeToTraceKind<T>::kind>::kind; | |||||
}; | |||||
template <typename T> | |||||
struct MapTypeToRootKind<mozilla::UniquePtr<T>> { | |||||
static const JS::RootKind kind = JS::MapTypeToRootKind<T>::kind; | |||||
}; | |||||
template <> struct MapTypeToRootKind<JS::Value> { | |||||
static const JS::RootKind kind = JS::RootKind::Value; | |||||
}; | |||||
template <> struct MapTypeToRootKind<jsid> { | |||||
static const JS::RootKind kind = JS::RootKind::Id; | |||||
}; | |||||
template <> struct MapTypeToRootKind<JSFunction*> : public MapTypeToRootKind<JSObject*> {}; | |||||
// Fortunately, few places in the system need to deal with fully abstract | // Fortunately, few places in the system need to deal with fully abstract | ||||
// cells. In those places that do, we generally want to move to a layout | // cells. In those places that do, we generally want to move to a layout | ||||
// templated function as soon as possible. This template wraps the upcast | // templated function as soon as possible. This template wraps the upcast | ||||
// for that dispatch. | // for that dispatch. | ||||
// | // | ||||
// Given a call: | // Given a call: | ||||
// | // | ||||
// DispatchTraceKindTyped(f, thing, traceKind, ... args) | // DispatchTraceKindTyped(f, thing, traceKind, ... args) | ||||
▲ Show 20 Lines • Show All 52 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator