mfbt/Alignment.h
author Boris Zbarsky <bzbarsky@mit.edu>
Wed, 24 Jun 2015 00:42:46 -0700
changeset 250045 4267b74ee795e8127ffce4d45d00384cd8170130
parent 193456 91d7659bb35145e10ff737753688e0972c1a79b5
child 255915 635fb4ea6b503321347b17a69f980b83430559b0
permissions -rw-r--r--
Bug 1176083. Remove the now-dead code for the XPCOM version of setTimeout/setInterval. r=smaug I claim this code is dead because on the one hand it's no longer called from JS (because Window is always on WebIDL bindings, but on the other hand it can't really be called from C++ because it depends on examining the XPConnect call information. I think removing this completely, including from the IDL, is safe, because nothing directly returns nsIDOMJSWindow, so anyone using its vtable would have to QI to it and we're changing the IID.

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/* Functionality related to memory alignment. */

#ifndef mozilla_Alignment_h
#define mozilla_Alignment_h

#include <stddef.h>
#include <stdint.h>

namespace mozilla {

/*
 * This class, and the corresponding macro MOZ_ALIGNOF, figures out how many
 * bytes of alignment a given type needs.
 */
template<typename T>
class AlignmentFinder
{
  struct Aligner
  {
    char mChar;
    T mT;
  };

public:
  static const size_t alignment = sizeof(Aligner) - sizeof(T);
};

#define MOZ_ALIGNOF(T) mozilla::AlignmentFinder<T>::alignment

/*
 * Declare the MOZ_ALIGNED_DECL macro for declaring aligned types.
 *
 * For instance,
 *
 *   MOZ_ALIGNED_DECL(char arr[2], 8);
 *
 * will declare a two-character array |arr| aligned to 8 bytes.
 */

#if defined(__GNUC__)
#  define MOZ_ALIGNED_DECL(_type, _align) \
     _type __attribute__((aligned(_align)))
#elif defined(_MSC_VER)
#  define MOZ_ALIGNED_DECL(_type, _align) \
     __declspec(align(_align)) _type
#else
#  warning "We don't know how to align variables on this compiler."
#  define MOZ_ALIGNED_DECL(_type, _align) _type
#endif

/*
 * AlignedElem<N> is a structure whose alignment is guaranteed to be at least N
 * bytes.
 *
 * We support 1, 2, 4, 8, and 16-bit alignment.
 */
template<size_t Align>
struct AlignedElem;

/*
 * We have to specialize this template because GCC doesn't like
 * __attribute__((aligned(foo))) where foo is a template parameter.
 */

template<>
struct AlignedElem<1>
{
  MOZ_ALIGNED_DECL(uint8_t elem, 1);
};

template<>
struct AlignedElem<2>
{
  MOZ_ALIGNED_DECL(uint8_t elem, 2);
};

template<>
struct AlignedElem<4>
{
  MOZ_ALIGNED_DECL(uint8_t elem, 4);
};

template<>
struct AlignedElem<8>
{
  MOZ_ALIGNED_DECL(uint8_t elem, 8);
};

template<>
struct AlignedElem<16>
{
  MOZ_ALIGNED_DECL(uint8_t elem, 16);
};

/*
 * This utility pales in comparison to Boost's aligned_storage. The utility
 * simply assumes that uint64_t is enough alignment for anyone. This may need
 * to be extended one day...
 *
 * As an important side effect, pulling the storage into this template is
 * enough obfuscation to confuse gcc's strict-aliasing analysis into not giving
 * false negatives when we cast from the char buffer to whatever type we've
 * constructed using the bytes.
 */
template<size_t Nbytes>
struct AlignedStorage
{
  union U
  {
    char mBytes[Nbytes];
    uint64_t mDummy;
  } u;

  const void* addr() const { return u.mBytes; }
  void* addr() { return u.mBytes; }
};

template<typename T>
struct AlignedStorage2
{
  union U
  {
    char mBytes[sizeof(T)];
    uint64_t mDummy;
  } u;

  const T* addr() const { return reinterpret_cast<const T*>(u.mBytes); }
  T* addr() { return static_cast<T*>(static_cast<void*>(u.mBytes)); }
};

} /* namespace mozilla */

#endif /* mozilla_Alignment_h */