mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 07:42:04 +00:00
Bug 689362 - Create js/public (with the intention that its contents will eventually be the only INSTALLED_HEADERS), move Vector and HashTable to js/public and some dependencies (r=billm,sr=dmandelin)
--HG-- rename : js/src/jshashtable.h => js/public/HashTable.h rename : js/src/jsvector.h => js/public/Vector.h rename : js/src/mfbt/InlineMap.h => js/src/ds/InlineMap.h extra : rebase_source : 818639b74653667b7a572bc1234398c0e4559a60
This commit is contained in:
parent
99ace2374d
commit
f90352c158
@ -40,7 +40,7 @@
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsvector.h"
|
||||
#include "js/Vector.h"
|
||||
|
||||
#include "Events.h"
|
||||
|
||||
|
@ -37,10 +37,10 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "jscntxt.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jshashtable.h"
|
||||
#include "jscntxt.h"
|
||||
#include "js/HashTable.h"
|
||||
|
||||
#include "mozilla/jetpack/JetpackActorCommon.h"
|
||||
#include "mozilla/jetpack/PJetpack.h"
|
||||
|
@ -43,9 +43,8 @@
|
||||
#ifndef jshashtable_h_
|
||||
#define jshashtable_h_
|
||||
|
||||
#include "jsalloc.h"
|
||||
#include "jstl.h"
|
||||
#include "jsutil.h"
|
||||
#include "TemplateLib.h"
|
||||
#include "Utility.h"
|
||||
|
||||
namespace js {
|
||||
|
@ -14,18 +14,19 @@
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released
|
||||
* July 16, 2009.
|
||||
* The Original Code is Mozilla SpiderMonkey JavaScript code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* the Mozilla Corporation.
|
||||
* the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Luke Wagner <lw@mozilla.com>
|
||||
* Luke Wagner <luke@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
@ -37,20 +38,20 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef jstl_h_
|
||||
#define jstl_h_
|
||||
#ifndef js_template_lib_h__
|
||||
#define js_template_lib_h__
|
||||
|
||||
#include "jsprvtd.h"
|
||||
#include "jsbit.h"
|
||||
#include "jsstaticcheck.h"
|
||||
#include "mozilla/Types.h"
|
||||
#include "jsstdint.h"
|
||||
|
||||
#include <new>
|
||||
#include <string.h>
|
||||
/*
|
||||
* Library of reusable template meta-functions (that is, functions on types and
|
||||
* compile-time values). Meta-functions are placed inside the 'tl' namespace to
|
||||
* avoid conflict with non-meta functions that logically have the same name
|
||||
* (e.g., js::tl::Min vs. js::Min).
|
||||
*/
|
||||
|
||||
namespace js {
|
||||
|
||||
/* JavaScript Template Library. */
|
||||
namespace tl {
|
||||
|
||||
/* Compute min/max/clamp. */
|
||||
@ -178,270 +179,6 @@ template <bool cond, typename T, T v1, T v2> struct If { static const T r
|
||||
template <typename T, T v1, T v2> struct If<false, T, v1, v2> { static const T result = v2; };
|
||||
|
||||
} /* namespace tl */
|
||||
|
||||
/* Useful for implementing containers that assert non-reentrancy */
|
||||
class ReentrancyGuard
|
||||
{
|
||||
/* ReentrancyGuard is not copyable. */
|
||||
ReentrancyGuard(const ReentrancyGuard &);
|
||||
void operator=(const ReentrancyGuard &);
|
||||
|
||||
#ifdef DEBUG
|
||||
bool &entered;
|
||||
#endif
|
||||
public:
|
||||
template <class T>
|
||||
#ifdef DEBUG
|
||||
ReentrancyGuard(T &obj)
|
||||
: entered(obj.entered)
|
||||
#else
|
||||
ReentrancyGuard(T &/*obj*/)
|
||||
#endif
|
||||
{
|
||||
#ifdef DEBUG
|
||||
JS_ASSERT(!entered);
|
||||
entered = true;
|
||||
#endif
|
||||
}
|
||||
~ReentrancyGuard()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
entered = false;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Round x up to the nearest power of 2. This function assumes that the most
|
||||
* significant bit of x is not set, which would lead to overflow.
|
||||
*/
|
||||
STATIC_POSTCONDITION_ASSUME(return >= x)
|
||||
JS_ALWAYS_INLINE size_t
|
||||
RoundUpPow2(size_t x)
|
||||
{
|
||||
size_t log2 = JS_CEILING_LOG2W(x);
|
||||
JS_ASSERT(log2 < tl::BitSize<size_t>::result);
|
||||
size_t result = size_t(1) << log2;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
class AlignedPtrAndFlag
|
||||
{
|
||||
uintptr_t bits;
|
||||
|
||||
public:
|
||||
AlignedPtrAndFlag(T *t, bool flag) {
|
||||
JS_ASSERT((uintptr_t(t) & 1) == 0);
|
||||
bits = uintptr_t(t) | uintptr_t(flag);
|
||||
}
|
||||
|
||||
T *ptr() const {
|
||||
return (T *)(bits & ~uintptr_t(1));
|
||||
}
|
||||
|
||||
bool flag() const {
|
||||
return (bits & 1) != 0;
|
||||
}
|
||||
|
||||
void setPtr(T *t) {
|
||||
JS_ASSERT((uintptr_t(t) & 1) == 0);
|
||||
bits = uintptr_t(t) | uintptr_t(flag());
|
||||
}
|
||||
|
||||
void setFlag() {
|
||||
bits |= 1;
|
||||
}
|
||||
|
||||
void unsetFlag() {
|
||||
bits &= ~uintptr_t(1);
|
||||
}
|
||||
|
||||
void set(T *t, bool flag) {
|
||||
JS_ASSERT((uintptr_t(t) & 1) == 0);
|
||||
bits = uintptr_t(t) | flag;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
static inline void
|
||||
Reverse(T *beg, T *end)
|
||||
{
|
||||
while (beg != end) {
|
||||
if (--end == beg)
|
||||
return;
|
||||
T tmp = *beg;
|
||||
*beg = *end;
|
||||
*end = tmp;
|
||||
++beg;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static inline T *
|
||||
Find(T *beg, T *end, const T &v)
|
||||
{
|
||||
for (T *p = beg; p != end; ++p) {
|
||||
if (*p == v)
|
||||
return p;
|
||||
}
|
||||
return end;
|
||||
}
|
||||
|
||||
template <class Container>
|
||||
static inline typename Container::ElementType *
|
||||
Find(Container &c, const typename Container::ElementType &v)
|
||||
{
|
||||
return Find(c.begin(), c.end(), v);
|
||||
}
|
||||
|
||||
template <typename InputIterT, typename CallableT>
|
||||
void
|
||||
ForEach(InputIterT begin, InputIterT end, CallableT f)
|
||||
{
|
||||
for (; begin != end; ++begin)
|
||||
f(*begin);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static inline T
|
||||
Min(T t1, T t2)
|
||||
{
|
||||
return t1 < t2 ? t1 : t2;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static inline T
|
||||
Max(T t1, T t2)
|
||||
{
|
||||
return t1 > t2 ? t1 : t2;
|
||||
}
|
||||
|
||||
/* Allows a const variable to be initialized after its declaration. */
|
||||
template <class T>
|
||||
static T&
|
||||
InitConst(const T &t)
|
||||
{
|
||||
return const_cast<T &>(t);
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
JS_ALWAYS_INLINE T &
|
||||
ImplicitCast(U &u)
|
||||
{
|
||||
T &t = u;
|
||||
return t;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
class AutoScopedAssign
|
||||
{
|
||||
private:
|
||||
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
T *addr;
|
||||
T old;
|
||||
|
||||
public:
|
||||
AutoScopedAssign(T *addr, const T &value JS_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: addr(addr), old(*addr)
|
||||
{
|
||||
JS_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
*addr = value;
|
||||
}
|
||||
|
||||
~AutoScopedAssign() { *addr = old; }
|
||||
};
|
||||
|
||||
template <class RefCountable>
|
||||
class AlreadyIncRefed
|
||||
{
|
||||
typedef RefCountable *****ConvertibleToBool;
|
||||
|
||||
RefCountable *obj;
|
||||
|
||||
public:
|
||||
explicit AlreadyIncRefed(RefCountable *obj) : obj(obj) {}
|
||||
|
||||
bool null() const { return obj == NULL; }
|
||||
operator ConvertibleToBool() const { return (ConvertibleToBool)obj; }
|
||||
|
||||
RefCountable *operator->() const { JS_ASSERT(!null()); return obj; }
|
||||
RefCountable &operator*() const { JS_ASSERT(!null()); return *obj; }
|
||||
RefCountable *get() const { return obj; }
|
||||
};
|
||||
|
||||
template <class RefCountable>
|
||||
class NeedsIncRef
|
||||
{
|
||||
typedef RefCountable *****ConvertibleToBool;
|
||||
|
||||
RefCountable *obj;
|
||||
|
||||
public:
|
||||
explicit NeedsIncRef(RefCountable *obj) : obj(obj) {}
|
||||
|
||||
bool null() const { return obj == NULL; }
|
||||
operator ConvertibleToBool() const { return (ConvertibleToBool)obj; }
|
||||
|
||||
RefCountable *operator->() const { JS_ASSERT(!null()); return obj; }
|
||||
RefCountable &operator*() const { JS_ASSERT(!null()); return *obj; }
|
||||
RefCountable *get() const { return obj; }
|
||||
};
|
||||
|
||||
template <class RefCountable>
|
||||
class AutoRefCount
|
||||
{
|
||||
typedef RefCountable *****ConvertibleToBool;
|
||||
|
||||
JSContext *const cx;
|
||||
RefCountable *obj;
|
||||
|
||||
AutoRefCount(const AutoRefCount &);
|
||||
void operator=(const AutoRefCount &);
|
||||
|
||||
public:
|
||||
explicit AutoRefCount(JSContext *cx)
|
||||
: cx(cx), obj(NULL)
|
||||
{}
|
||||
|
||||
AutoRefCount(JSContext *cx, NeedsIncRef<RefCountable> aobj)
|
||||
: cx(cx), obj(aobj.get())
|
||||
{
|
||||
if (obj)
|
||||
obj->incref(cx);
|
||||
}
|
||||
|
||||
AutoRefCount(JSContext *cx, AlreadyIncRefed<RefCountable> aobj)
|
||||
: cx(cx), obj(aobj.get())
|
||||
{}
|
||||
|
||||
~AutoRefCount() {
|
||||
if (obj)
|
||||
obj->decref(cx);
|
||||
}
|
||||
|
||||
void reset(NeedsIncRef<RefCountable> aobj) {
|
||||
if (obj)
|
||||
obj->decref(cx);
|
||||
obj = aobj.get();
|
||||
if (obj)
|
||||
obj->incref(cx);
|
||||
}
|
||||
|
||||
void reset(AlreadyIncRefed<RefCountable> aobj) {
|
||||
if (obj)
|
||||
obj->decref(cx);
|
||||
obj = aobj.get();
|
||||
}
|
||||
|
||||
bool null() const { return obj == NULL; }
|
||||
operator ConvertibleToBool() const { return (ConvertibleToBool)obj; }
|
||||
|
||||
RefCountable *operator->() const { JS_ASSERT(!null()); return obj; }
|
||||
RefCountable &operator*() const { JS_ASSERT(!null()); return *obj; }
|
||||
RefCountable *get() const { return obj; }
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* jstl_h_ */
|
||||
#endif /* js_template_lib_h__ */
|
945
js/public/Utility.h
Normal file
945
js/public/Utility.h
Normal file
@ -0,0 +1,945 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=99 ft=cpp:
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla SpiderMonkey JavaScript code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef js_utility_h__
|
||||
#define js_utility_h__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mozilla/Util.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
/* The public JS engine namespace. */
|
||||
namespace JS {}
|
||||
|
||||
/* The mozilla-shared reusable template/utility namespace. */
|
||||
namespace mozilla {}
|
||||
|
||||
/* The private JS engine namespace. */
|
||||
namespace js {
|
||||
|
||||
/* The private namespace is a superset of the public/shared namespaces. */
|
||||
using namespace JS;
|
||||
using namespace mozilla;
|
||||
|
||||
} /* namespace js */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
JS_BEGIN_EXTERN_C
|
||||
|
||||
/*
|
||||
* Pattern used to overwrite freed memory. If you are accessing an object with
|
||||
* this pattern, you probably have a dangling pointer.
|
||||
*/
|
||||
#define JS_FREE_PATTERN 0xDA
|
||||
|
||||
/* JS_ASSERT */
|
||||
#ifdef DEBUG
|
||||
# define JS_ASSERT(expr) \
|
||||
((expr) ? (void)0 : JS_Assert(#expr, __FILE__, __LINE__))
|
||||
# define JS_ASSERT_IF(cond, expr) \
|
||||
((!(cond) || (expr)) ? (void)0 : JS_Assert(#expr, __FILE__, __LINE__))
|
||||
# define JS_NOT_REACHED(reason) \
|
||||
JS_Assert(reason, __FILE__, __LINE__)
|
||||
# define JS_ALWAYS_TRUE(expr) JS_ASSERT(expr)
|
||||
# define JS_ALWAYS_FALSE(expr) JS_ASSERT(!(expr))
|
||||
# ifdef JS_THREADSAFE
|
||||
# define JS_THREADSAFE_ASSERT(expr) JS_ASSERT(expr)
|
||||
# else
|
||||
# define JS_THREADSAFE_ASSERT(expr) ((void) 0)
|
||||
# endif
|
||||
#else
|
||||
# define JS_ASSERT(expr) ((void) 0)
|
||||
# define JS_ASSERT_IF(cond,expr) ((void) 0)
|
||||
# define JS_NOT_REACHED(reason)
|
||||
# define JS_ALWAYS_TRUE(expr) ((void) (expr))
|
||||
# define JS_ALWAYS_FALSE(expr) ((void) (expr))
|
||||
# define JS_THREADSAFE_ASSERT(expr) ((void) 0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* JS_STATIC_ASSERT
|
||||
*
|
||||
* A compile-time assert. "cond" must be a constant expression. The macro can
|
||||
* be used only in places where an "extern" declaration is allowed.
|
||||
*/
|
||||
#ifdef __SUNPRO_CC
|
||||
/*
|
||||
* Sun Studio C++ compiler has a bug
|
||||
* "sizeof expression not accepted as size of array parameter"
|
||||
* It happens when js_static_assert() function is declared inside functions.
|
||||
* The bug number is 6688515. It is not public yet.
|
||||
* Therefore, for Sun Studio, declare js_static_assert as an array instead.
|
||||
*/
|
||||
# define JS_STATIC_ASSERT(cond) extern char js_static_assert[(cond) ? 1 : -1]
|
||||
#else
|
||||
# ifdef __COUNTER__
|
||||
# define JS_STATIC_ASSERT_GLUE1(x,y) x##y
|
||||
# define JS_STATIC_ASSERT_GLUE(x,y) JS_STATIC_ASSERT_GLUE1(x,y)
|
||||
# define JS_STATIC_ASSERT(cond) \
|
||||
typedef int JS_STATIC_ASSERT_GLUE(js_static_assert, __COUNTER__)[(cond) ? 1 : -1]
|
||||
# else
|
||||
# define JS_STATIC_ASSERT(cond) extern void js_static_assert(int arg[(cond) ? 1 : -1])
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define JS_STATIC_ASSERT_IF(cond, expr) JS_STATIC_ASSERT(!(cond) || (expr))
|
||||
|
||||
/*
|
||||
* Abort the process in a non-graceful manner. This will cause a core file,
|
||||
* call to the debugger or other moral equivalent as well as causing the
|
||||
* entire process to stop.
|
||||
*/
|
||||
extern JS_PUBLIC_API(void) JS_Abort(void);
|
||||
|
||||
/*
|
||||
* Custom allocator support for SpiderMonkey
|
||||
*/
|
||||
#if defined JS_USE_CUSTOM_ALLOCATOR
|
||||
# include "jscustomallocator.h"
|
||||
#else
|
||||
# ifdef DEBUG
|
||||
/*
|
||||
* In order to test OOM conditions, when the shell command-line option
|
||||
* |-A NUM| is passed, we fail continuously after the NUM'th allocation.
|
||||
*/
|
||||
extern JS_PUBLIC_DATA(JSUint32) OOM_maxAllocations; /* set from shell/js.cpp */
|
||||
extern JS_PUBLIC_DATA(JSUint32) OOM_counter; /* data race, who cares. */
|
||||
# define JS_OOM_POSSIBLY_FAIL() \
|
||||
do \
|
||||
{ \
|
||||
if (OOM_counter++ >= OOM_maxAllocations) { \
|
||||
return NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
# else
|
||||
# define JS_OOM_POSSIBLY_FAIL() do {} while(0)
|
||||
# endif
|
||||
|
||||
/*
|
||||
* SpiderMonkey code should not be calling these allocation functions directly.
|
||||
* Instead, all calls should go through JSRuntime, JSContext or OffTheBooks.
|
||||
* However, js_free() can be called directly.
|
||||
*/
|
||||
static JS_INLINE void* js_malloc(size_t bytes)
|
||||
{
|
||||
JS_OOM_POSSIBLY_FAIL();
|
||||
return malloc(bytes);
|
||||
}
|
||||
|
||||
static JS_INLINE void* js_calloc(size_t bytes)
|
||||
{
|
||||
JS_OOM_POSSIBLY_FAIL();
|
||||
return calloc(bytes, 1);
|
||||
}
|
||||
|
||||
static JS_INLINE void* js_realloc(void* p, size_t bytes)
|
||||
{
|
||||
JS_OOM_POSSIBLY_FAIL();
|
||||
return realloc(p, bytes);
|
||||
}
|
||||
|
||||
static JS_INLINE void js_free(void* p)
|
||||
{
|
||||
free(p);
|
||||
}
|
||||
#endif/* JS_USE_CUSTOM_ALLOCATOR */
|
||||
|
||||
/*
|
||||
* Replace bit-scanning code sequences with CPU-specific instructions to
|
||||
* speedup calculations of ceiling/floor log2.
|
||||
*
|
||||
* With GCC 3.4 or later we can use __builtin_clz for that, see bug 327129.
|
||||
*
|
||||
* SWS: Added MSVC intrinsic bitscan support. See bugs 349364 and 356856.
|
||||
*/
|
||||
#if defined(_WIN32) && (_MSC_VER >= 1300) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
|
||||
|
||||
unsigned char _BitScanForward(unsigned long * Index, unsigned long Mask);
|
||||
unsigned char _BitScanReverse(unsigned long * Index, unsigned long Mask);
|
||||
# pragma intrinsic(_BitScanForward,_BitScanReverse)
|
||||
|
||||
__forceinline static int
|
||||
__BitScanForward32(unsigned int val)
|
||||
{
|
||||
unsigned long idx;
|
||||
|
||||
_BitScanForward(&idx, (unsigned long)val);
|
||||
return (int)idx;
|
||||
}
|
||||
__forceinline static int
|
||||
__BitScanReverse32(unsigned int val)
|
||||
{
|
||||
unsigned long idx;
|
||||
|
||||
_BitScanReverse(&idx, (unsigned long)val);
|
||||
return (int)(31-idx);
|
||||
}
|
||||
# define js_bitscan_ctz32(val) __BitScanForward32(val)
|
||||
# define js_bitscan_clz32(val) __BitScanReverse32(val)
|
||||
# define JS_HAS_BUILTIN_BITSCAN32
|
||||
|
||||
#if defined(_M_AMD64) || defined(_M_X64)
|
||||
unsigned char _BitScanForward64(unsigned long * Index, unsigned __int64 Mask);
|
||||
unsigned char _BitScanReverse64(unsigned long * Index, unsigned __int64 Mask);
|
||||
# pragma intrinsic(_BitScanForward64,_BitScanReverse64)
|
||||
|
||||
__forceinline static int
|
||||
__BitScanForward64(unsigned __int64 val)
|
||||
{
|
||||
unsigned long idx;
|
||||
|
||||
_BitScanForward64(&idx, val);
|
||||
return (int)idx;
|
||||
}
|
||||
__forceinline static int
|
||||
__BitScanReverse64(unsigned __int64 val)
|
||||
{
|
||||
unsigned long idx;
|
||||
|
||||
_BitScanReverse64(&idx, val);
|
||||
return (int)(63-idx);
|
||||
}
|
||||
# define js_bitscan_ctz64(val) __BitScanForward64(val)
|
||||
# define js_bitscan_clz64(val) __BitScanReverse64(val)
|
||||
# define JS_HAS_BUILTIN_BITSCAN64
|
||||
#endif
|
||||
#elif (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
|
||||
|
||||
# define js_bitscan_ctz32(val) __builtin_ctz(val)
|
||||
# define js_bitscan_clz32(val) __builtin_clz(val)
|
||||
# define JS_HAS_BUILTIN_BITSCAN32
|
||||
# if (JS_BYTES_PER_WORD == 8)
|
||||
# define js_bitscan_ctz64(val) __builtin_ctzll(val)
|
||||
# define js_bitscan_clz64(val) __builtin_clzll(val)
|
||||
# define JS_HAS_BUILTIN_BITSCAN64
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Macro version of JS_CeilingLog2: Compute the log of the least power of
|
||||
** 2 greater than or equal to _n. The result is returned in _log2.
|
||||
*/
|
||||
#ifdef JS_HAS_BUILTIN_BITSCAN32
|
||||
/*
|
||||
* Use intrinsic function or count-leading-zeros to calculate ceil(log2(_n)).
|
||||
* The macro checks for "n <= 1" and not "n != 0" as js_bitscan_clz32(0) is
|
||||
* undefined.
|
||||
*/
|
||||
# define JS_CEILING_LOG2(_log2,_n) \
|
||||
JS_BEGIN_MACRO \
|
||||
unsigned int j_ = (unsigned int)(_n); \
|
||||
(_log2) = (j_ <= 1 ? 0 : 32 - js_bitscan_clz32(j_ - 1)); \
|
||||
JS_END_MACRO
|
||||
#else
|
||||
# define JS_CEILING_LOG2(_log2,_n) \
|
||||
JS_BEGIN_MACRO \
|
||||
JSUint32 j_ = (JSUint32)(_n); \
|
||||
(_log2) = 0; \
|
||||
if ((j_) & ((j_)-1)) \
|
||||
(_log2) += 1; \
|
||||
if ((j_) >> 16) \
|
||||
(_log2) += 16, (j_) >>= 16; \
|
||||
if ((j_) >> 8) \
|
||||
(_log2) += 8, (j_) >>= 8; \
|
||||
if ((j_) >> 4) \
|
||||
(_log2) += 4, (j_) >>= 4; \
|
||||
if ((j_) >> 2) \
|
||||
(_log2) += 2, (j_) >>= 2; \
|
||||
if ((j_) >> 1) \
|
||||
(_log2) += 1; \
|
||||
JS_END_MACRO
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Macro version of JS_FloorLog2: Compute the log of the greatest power of
|
||||
** 2 less than or equal to _n. The result is returned in _log2.
|
||||
**
|
||||
** This is equivalent to finding the highest set bit in the word.
|
||||
*/
|
||||
#ifdef JS_HAS_BUILTIN_BITSCAN32
|
||||
/*
|
||||
* Use js_bitscan_clz32 or count-leading-zeros to calculate floor(log2(_n)).
|
||||
* Since js_bitscan_clz32(0) is undefined, the macro set the loweset bit to 1
|
||||
* to ensure 0 result when _n == 0.
|
||||
*/
|
||||
# define JS_FLOOR_LOG2(_log2,_n) \
|
||||
JS_BEGIN_MACRO \
|
||||
(_log2) = 31 - js_bitscan_clz32(((unsigned int)(_n)) | 1); \
|
||||
JS_END_MACRO
|
||||
#else
|
||||
# define JS_FLOOR_LOG2(_log2,_n) \
|
||||
JS_BEGIN_MACRO \
|
||||
JSUint32 j_ = (JSUint32)(_n); \
|
||||
(_log2) = 0; \
|
||||
if ((j_) >> 16) \
|
||||
(_log2) += 16, (j_) >>= 16; \
|
||||
if ((j_) >> 8) \
|
||||
(_log2) += 8, (j_) >>= 8; \
|
||||
if ((j_) >> 4) \
|
||||
(_log2) += 4, (j_) >>= 4; \
|
||||
if ((j_) >> 2) \
|
||||
(_log2) += 2, (j_) >>= 2; \
|
||||
if ((j_) >> 1) \
|
||||
(_log2) += 1; \
|
||||
JS_END_MACRO
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Internal function.
|
||||
* Compute the log of the least power of 2 greater than or equal to n. This is
|
||||
* a version of JS_CeilingLog2 that operates on unsigned integers with
|
||||
* CPU-dependant size.
|
||||
*/
|
||||
#define JS_CEILING_LOG2W(n) ((n) <= 1 ? 0 : 1 + JS_FLOOR_LOG2W((n) - 1))
|
||||
|
||||
/*
|
||||
* Internal function.
|
||||
* Compute the log of the greatest power of 2 less than or equal to n.
|
||||
* This is a version of JS_FloorLog2 that operates on unsigned integers with
|
||||
* CPU-dependant size and requires that n != 0.
|
||||
*/
|
||||
#define JS_FLOOR_LOG2W(n) (JS_ASSERT((n) != 0), js_FloorLog2wImpl(n))
|
||||
|
||||
#if JS_BYTES_PER_WORD == 4
|
||||
# ifdef JS_HAS_BUILTIN_BITSCAN32
|
||||
# define js_FloorLog2wImpl(n) \
|
||||
((size_t)(JS_BITS_PER_WORD - 1 - js_bitscan_clz32(n)))
|
||||
# else
|
||||
# define js_FloorLog2wImpl(n) ((size_t)JS_FloorLog2(n))
|
||||
# endif
|
||||
#elif JS_BYTES_PER_WORD == 8
|
||||
# ifdef JS_HAS_BUILTIN_BITSCAN64
|
||||
# define js_FloorLog2wImpl(n) \
|
||||
((size_t)(JS_BITS_PER_WORD - 1 - js_bitscan_clz64(n)))
|
||||
# else
|
||||
extern size_t js_FloorLog2wImpl(size_t n);
|
||||
# endif
|
||||
#else
|
||||
# error "NOT SUPPORTED"
|
||||
#endif
|
||||
|
||||
JS_END_EXTERN_C
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <new>
|
||||
|
||||
/*
|
||||
* User guide to memory management within SpiderMonkey:
|
||||
*
|
||||
* Quick tips:
|
||||
*
|
||||
* Allocation:
|
||||
* - Prefer to allocate using JSContext:
|
||||
* cx->{malloc_,realloc_,calloc_,new_,array_new}
|
||||
*
|
||||
* - If no JSContext is available, use a JSRuntime:
|
||||
* rt->{malloc_,realloc_,calloc_,new_,array_new}
|
||||
*
|
||||
* - As a last resort, use unaccounted allocation ("OffTheBooks"):
|
||||
* js::OffTheBooks::{malloc_,realloc_,calloc_,new_,array_new}
|
||||
*
|
||||
* Deallocation:
|
||||
* - When the deallocation occurs on a slow path, use:
|
||||
* Foreground::{free_,delete_,array_delete}
|
||||
*
|
||||
* - Otherwise deallocate on a background thread using a JSContext:
|
||||
* cx->{free_,delete_,array_delete}
|
||||
*
|
||||
* - If no JSContext is available, use a JSRuntime:
|
||||
* rt->{free_,delete_,array_delete}
|
||||
*
|
||||
* - As a last resort, use UnwantedForeground deallocation:
|
||||
* js::UnwantedForeground::{free_,delete_,array_delete}
|
||||
*
|
||||
* General tips:
|
||||
*
|
||||
* - Mixing and matching these allocators is allowed (you may free memory
|
||||
* allocated by any allocator, with any deallocator).
|
||||
*
|
||||
* - Never, ever use normal C/C++ memory management:
|
||||
* malloc, free, new, new[], delete, operator new, etc.
|
||||
*
|
||||
* - Never, ever use low-level SpiderMonkey allocators:
|
||||
* js_malloc(), js_free(), js_calloc(), js_realloc()
|
||||
* Their use is reserved for the other memory managers.
|
||||
*
|
||||
* - Classes which have private constructors or destructors should have
|
||||
* JS_DECLARE_ALLOCATION_FRIENDS_FOR_PRIVATE_CONSTRUCTOR added to their
|
||||
* declaration.
|
||||
*
|
||||
* Details:
|
||||
*
|
||||
* Using vanilla new/new[] is unsafe in SpiderMonkey because they throw on
|
||||
* failure instead of returning NULL, which is what SpiderMonkey expects.
|
||||
* (Even overriding them is unsafe, as the system's C++ runtime library may
|
||||
* throw, which we do not support. We also can't just use the 'nothrow'
|
||||
* variant of new/new[], because we want to mediate *all* allocations
|
||||
* within SpiderMonkey, to satisfy any embedders using
|
||||
* JS_USE_CUSTOM_ALLOCATOR.)
|
||||
*
|
||||
* JSContexts and JSRuntimes keep track of memory allocated, and use this
|
||||
* accounting to schedule GC. OffTheBooks does not. We'd like to remove
|
||||
* OffTheBooks allocations as much as possible (bug 636558).
|
||||
*
|
||||
* On allocation failure, a JSContext correctly reports an error, which a
|
||||
* JSRuntime and OffTheBooks does not.
|
||||
*
|
||||
* A JSContext deallocates in a background thread. A JSRuntime might
|
||||
* deallocate in the background in the future, but does not now. Foreground
|
||||
* deallocation is preferable on slow paths. UnwantedForeground deallocations
|
||||
* occur where we have no JSContext or JSRuntime, and the deallocation is not
|
||||
* on a slow path. We want to remove UnwantedForeground deallocations (bug
|
||||
* 636561).
|
||||
*
|
||||
* JS_DECLARE_ALLOCATION_FRIENDS_FOR_PRIVATE_CONSTRUCTOR makes the allocation
|
||||
* classes friends with your class, giving them access to private
|
||||
* constructors and destructors.
|
||||
*
|
||||
* |make check| does a source level check on the number of uses OffTheBooks,
|
||||
* UnwantedForeground, js_malloc, js_free etc, to prevent regressions. If you
|
||||
* really must add one, update Makefile.in, and run |make check|.
|
||||
*
|
||||
* |make check| also statically prevents the use of vanilla new/new[].
|
||||
*/
|
||||
|
||||
#define JS_NEW_BODY(allocator, t, parms) \
|
||||
void *memory = allocator(sizeof(t)); \
|
||||
return memory ? new(memory) t parms : NULL;
|
||||
|
||||
/*
|
||||
* Given a class which should provide new_() methods, add
|
||||
* JS_DECLARE_NEW_METHODS (see JSContext for a usage example). This
|
||||
* adds new_()s with up to 12 parameters. Add more versions of new_ below if
|
||||
* you need more than 12 parameters.
|
||||
*
|
||||
* Note: Do not add a ; at the end of a use of JS_DECLARE_NEW_METHODS,
|
||||
* or the build will break.
|
||||
*/
|
||||
#define JS_DECLARE_NEW_METHODS(ALLOCATOR, QUALIFIERS)\
|
||||
template <class T>\
|
||||
QUALIFIERS T *new_() {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, ())\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1>\
|
||||
QUALIFIERS T *new_(P1 p1) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3, class P4>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5, class P6>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6, p7))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6, p7, p8))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6, p7, p8, p9))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10, class P11>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11))\
|
||||
}\
|
||||
\
|
||||
template <class T, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10, class P11, class P12>\
|
||||
QUALIFIERS T *new_(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11, P12 p12) {\
|
||||
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12))\
|
||||
}\
|
||||
static const int JSMinAlignment = 8;\
|
||||
template <class T>\
|
||||
QUALIFIERS T *array_new(size_t n) {\
|
||||
/* The length is stored just before the vector memory. */\
|
||||
uint64 numBytes64 = uint64(JSMinAlignment) + uint64(sizeof(T)) * uint64(n);\
|
||||
size_t numBytes = size_t(numBytes64);\
|
||||
if (numBytes64 != numBytes) {\
|
||||
JS_ASSERT(0); /* we want to know if this happens in debug builds */\
|
||||
return NULL;\
|
||||
}\
|
||||
void *memory = ALLOCATOR(numBytes);\
|
||||
if (!memory)\
|
||||
return NULL;\
|
||||
*(size_t *)memory = n;\
|
||||
memory = (void*)(uintptr_t(memory) + JSMinAlignment);\
|
||||
return new(memory) T[n];\
|
||||
}\
|
||||
|
||||
|
||||
#define JS_DECLARE_DELETE_METHODS(DEALLOCATOR, QUALIFIERS)\
|
||||
template <class T>\
|
||||
QUALIFIERS void delete_(T *p) {\
|
||||
if (p) {\
|
||||
p->~T();\
|
||||
DEALLOCATOR(p);\
|
||||
}\
|
||||
}\
|
||||
\
|
||||
template <class T>\
|
||||
QUALIFIERS void array_delete(T *p) {\
|
||||
if (p) {\
|
||||
void* p0 = (void *)(uintptr_t(p) - js::OffTheBooks::JSMinAlignment);\
|
||||
size_t n = *(size_t *)p0;\
|
||||
for (size_t i = 0; i < n; i++)\
|
||||
(p + i)->~T();\
|
||||
DEALLOCATOR(p0);\
|
||||
}\
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* In general, all allocations should go through a JSContext or JSRuntime, so
|
||||
* that the garbage collector knows how much memory has been allocated. In
|
||||
* cases where it is difficult to use a JSContext or JSRuntime, OffTheBooks can
|
||||
* be used, though this is undesirable.
|
||||
*/
|
||||
namespace js {
|
||||
|
||||
class OffTheBooks {
|
||||
public:
|
||||
JS_DECLARE_NEW_METHODS(::js_malloc, JS_ALWAYS_INLINE static)
|
||||
|
||||
static JS_INLINE void* malloc_(size_t bytes) {
|
||||
return ::js_malloc(bytes);
|
||||
}
|
||||
|
||||
static JS_INLINE void* calloc_(size_t bytes) {
|
||||
return ::js_calloc(bytes);
|
||||
}
|
||||
|
||||
static JS_INLINE void* realloc_(void* p, size_t bytes) {
|
||||
return ::js_realloc(p, bytes);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* We generally prefer deallocating using JSContext because it can happen in
|
||||
* the background. On slow paths, we may prefer foreground allocation.
|
||||
*/
|
||||
class Foreground {
|
||||
public:
|
||||
/* See parentheses comment above. */
|
||||
static JS_ALWAYS_INLINE void free_(void* p) {
|
||||
::js_free(p);
|
||||
}
|
||||
|
||||
JS_DECLARE_DELETE_METHODS(::js_free, JS_ALWAYS_INLINE static)
|
||||
};
|
||||
|
||||
class UnwantedForeground : public Foreground {
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
/*
|
||||
* Note lack of ; in JSRuntime below. This is intentional so "calling" this
|
||||
* looks "normal".
|
||||
*/
|
||||
#define JS_DECLARE_ALLOCATION_FRIENDS_FOR_PRIVATE_CONSTRUCTOR \
|
||||
friend class js::OffTheBooks;\
|
||||
friend class js::Foreground;\
|
||||
friend class js::UnwantedForeground;\
|
||||
friend struct ::JSContext;\
|
||||
friend struct ::JSRuntime
|
||||
|
||||
/*
|
||||
* The following classes are designed to cause assertions to detect
|
||||
* inadvertent use of guard objects as temporaries. In other words,
|
||||
* when we have a guard object whose only purpose is its constructor and
|
||||
* destructor (and is never otherwise referenced), the intended use
|
||||
* might be:
|
||||
* JSAutoTempValueRooter tvr(cx, 1, &val);
|
||||
* but is is easy to accidentally write:
|
||||
* JSAutoTempValueRooter(cx, 1, &val);
|
||||
* which compiles just fine, but runs the destructor well before the
|
||||
* intended time.
|
||||
*
|
||||
* They work by adding (#ifdef DEBUG) an additional parameter to the
|
||||
* guard object's constructor, with a default value, so that users of
|
||||
* the guard object's API do not need to do anything. The default value
|
||||
* of this parameter is a temporary object. C++ (ISO/IEC 14882:1998),
|
||||
* section 12.2 [class.temporary], clauses 4 and 5 seem to assume a
|
||||
* guarantee that temporaries are destroyed in the reverse of their
|
||||
* construction order, but I actually can't find a statement that that
|
||||
* is true in the general case (beyond the two specific cases mentioned
|
||||
* there). However, it seems to be true.
|
||||
*
|
||||
* These classes are intended to be used only via the macros immediately
|
||||
* below them:
|
||||
* JS_DECL_USE_GUARD_OBJECT_NOTIFIER declares (ifdef DEBUG) a member
|
||||
* variable, and should be put where a declaration of a private
|
||||
* member variable would be placed.
|
||||
* JS_GUARD_OBJECT_NOTIFIER_PARAM should be placed at the end of the
|
||||
* parameters to each constructor of the guard object; it declares
|
||||
* (ifdef DEBUG) an additional parameter.
|
||||
* JS_GUARD_OBJECT_NOTIFIER_INIT is a statement that belongs in each
|
||||
* constructor. It uses the parameter declared by
|
||||
* JS_GUARD_OBJECT_NOTIFIER_PARAM.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
class JS_FRIEND_API(JSGuardObjectNotifier)
|
||||
{
|
||||
private:
|
||||
bool* mStatementDone;
|
||||
public:
|
||||
JSGuardObjectNotifier() : mStatementDone(NULL) {}
|
||||
|
||||
~JSGuardObjectNotifier() {
|
||||
*mStatementDone = true;
|
||||
}
|
||||
|
||||
void setStatementDone(bool *aStatementDone) {
|
||||
mStatementDone = aStatementDone;
|
||||
}
|
||||
};
|
||||
|
||||
class JS_FRIEND_API(JSGuardObjectNotificationReceiver)
|
||||
{
|
||||
private:
|
||||
bool mStatementDone;
|
||||
public:
|
||||
JSGuardObjectNotificationReceiver() : mStatementDone(false) {}
|
||||
|
||||
~JSGuardObjectNotificationReceiver() {
|
||||
/*
|
||||
* Assert that the guard object was not used as a temporary.
|
||||
* (Note that this assert might also fire if Init is not called
|
||||
* because the guard object's implementation is not using the
|
||||
* above macros correctly.)
|
||||
*/
|
||||
JS_ASSERT(mStatementDone);
|
||||
}
|
||||
|
||||
void Init(const JSGuardObjectNotifier &aNotifier) {
|
||||
/*
|
||||
* aNotifier is passed as a const reference so that we can pass a
|
||||
* temporary, but we really intend it as non-const
|
||||
*/
|
||||
const_cast<JSGuardObjectNotifier&>(aNotifier).
|
||||
setStatementDone(&mStatementDone);
|
||||
}
|
||||
};
|
||||
|
||||
#define JS_DECL_USE_GUARD_OBJECT_NOTIFIER \
|
||||
JSGuardObjectNotificationReceiver _mCheckNotUsedAsTemporary;
|
||||
#define JS_GUARD_OBJECT_NOTIFIER_PARAM \
|
||||
, const JSGuardObjectNotifier& _notifier = JSGuardObjectNotifier()
|
||||
#define JS_GUARD_OBJECT_NOTIFIER_PARAM_NO_INIT \
|
||||
, const JSGuardObjectNotifier& _notifier
|
||||
#define JS_GUARD_OBJECT_NOTIFIER_PARAM0 \
|
||||
const JSGuardObjectNotifier& _notifier = JSGuardObjectNotifier()
|
||||
#define JS_GUARD_OBJECT_NOTIFIER_INIT \
|
||||
JS_BEGIN_MACRO _mCheckNotUsedAsTemporary.Init(_notifier); JS_END_MACRO
|
||||
|
||||
#else /* defined(DEBUG) */
|
||||
|
||||
#define JS_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
#define JS_GUARD_OBJECT_NOTIFIER_PARAM
|
||||
#define JS_GUARD_OBJECT_NOTIFIER_PARAM_NO_INIT
|
||||
#define JS_GUARD_OBJECT_NOTIFIER_PARAM0
|
||||
#define JS_GUARD_OBJECT_NOTIFIER_INIT JS_BEGIN_MACRO JS_END_MACRO
|
||||
|
||||
#endif /* !defined(DEBUG) */
|
||||
|
||||
namespace js {
|
||||
|
||||
/*
|
||||
* "Move" References
|
||||
*
|
||||
* Some types can be copied much more efficiently if we know the original's
|
||||
* value need not be preserved --- that is, if we are doing a "move", not a
|
||||
* "copy". For example, if we have:
|
||||
*
|
||||
* Vector<T> u;
|
||||
* Vector<T> v(u);
|
||||
*
|
||||
* the constructor for v must apply a copy constructor to each element of u ---
|
||||
* taking time linear in the length of u. However, if we know we will not need u
|
||||
* any more once v has been initialized, then we could initialize v very
|
||||
* efficiently simply by stealing u's dynamically allocated buffer and giving it
|
||||
* to v --- a constant-time operation, regardless of the size of u.
|
||||
*
|
||||
* Moves often appear in container implementations. For example, when we append
|
||||
* to a vector, we may need to resize its buffer. This entails moving each of
|
||||
* its extant elements from the old, smaller buffer to the new, larger buffer.
|
||||
* But once the elements have been migrated, we're just going to throw away the
|
||||
* old buffer; we don't care if they still have their values. So if the vector's
|
||||
* element type can implement "move" more efficiently than "copy", the vector
|
||||
* resizing should by all means use a "move" operation. Hash tables also need to
|
||||
* be resized.
|
||||
*
|
||||
* The details of the optimization, and whether it's worth applying, vary from
|
||||
* one type to the next. And while some constructor calls are moves, many really
|
||||
* are copies, and can't be optimized this way. So we need:
|
||||
*
|
||||
* 1) a way for a particular invocation of a copy constructor to say that it's
|
||||
* really a move, and that the value of the original isn't important
|
||||
* afterwards (althought it must still be safe to destroy); and
|
||||
*
|
||||
* 2) a way for a type (like Vector) to announce that it can be moved more
|
||||
* efficiently than it can be copied, and provide an implementation of that
|
||||
* move operation.
|
||||
*
|
||||
* The Move(T &) function takes a reference to a T, and returns an MoveRef<T>
|
||||
* referring to the same value; that's 1). An MoveRef<T> is simply a reference
|
||||
* to a T, annotated to say that a copy constructor applied to it may move that
|
||||
* T, instead of copying it. Finally, a constructor that accepts an MoveRef<T>
|
||||
* should perform a more efficient move, instead of a copy, providing 2).
|
||||
*
|
||||
* So, where we might define a copy constructor for a class C like this:
|
||||
*
|
||||
* C(const C &rhs) { ... copy rhs to this ... }
|
||||
*
|
||||
* we would declare a move constructor like this:
|
||||
*
|
||||
* C(MoveRef<C> rhs) { ... move rhs to this ... }
|
||||
*
|
||||
* And where we might perform a copy like this:
|
||||
*
|
||||
* C c2(c1);
|
||||
*
|
||||
* we would perform a move like this:
|
||||
*
|
||||
* C c2(Move(c1))
|
||||
*
|
||||
* Note that MoveRef<T> implicitly converts to T &, so you can pass an
|
||||
* MoveRef<T> to an ordinary copy constructor for a type that doesn't support a
|
||||
* special move constructor, and you'll just get a copy. This means that
|
||||
* templates can use Move whenever they know they won't use the original value
|
||||
* any more, even if they're not sure whether the type at hand has a specialized
|
||||
* move constructor. If it doesn't, the MoveRef<T> will just convert to a T &,
|
||||
* and the ordinary copy constructor will apply.
|
||||
*
|
||||
* A class with a move constructor can also provide a move assignment operator,
|
||||
* which runs this's destructor, and then applies the move constructor to
|
||||
* *this's memory. A typical definition:
|
||||
*
|
||||
* C &operator=(MoveRef<C> rhs) {
|
||||
* this->~C();
|
||||
* new(this) C(rhs);
|
||||
* return *this;
|
||||
* }
|
||||
*
|
||||
* With that in place, one can write move assignments like this:
|
||||
*
|
||||
* c2 = Move(c1);
|
||||
*
|
||||
* This destroys c1, moves c1's value to c2, and leaves c1 in an undefined but
|
||||
* destructible state.
|
||||
*
|
||||
* This header file defines MoveRef and Move in the js namespace. It's up to
|
||||
* individual containers to annotate moves as such, by calling Move; and it's up
|
||||
* to individual types to define move constructors.
|
||||
*
|
||||
* One hint: if you're writing a move constructor where the type has members
|
||||
* that should be moved themselves, it's much nicer to write this:
|
||||
*
|
||||
* C(MoveRef<C> c) : x(c->x), y(c->y) { }
|
||||
*
|
||||
* than the equivalent:
|
||||
*
|
||||
* C(MoveRef<C> c) { new(&x) X(c->x); new(&y) Y(c->y); }
|
||||
*
|
||||
* especially since GNU C++ fails to notice that this does indeed initialize x
|
||||
* and y, which may matter if they're const.
|
||||
*/
|
||||
template<typename T>
|
||||
class MoveRef {
|
||||
public:
|
||||
typedef T Referent;
|
||||
explicit MoveRef(T &t) : pointer(&t) { }
|
||||
T &operator*() const { return *pointer; }
|
||||
T *operator->() const { return pointer; }
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
/*
|
||||
* If MoveRef is used in a rvalue position (which is expected), we can
|
||||
* end up in a situation where, without this ifdef, we would try to pass
|
||||
* a T& to a move constructor, which fails. It is not clear if the compiler
|
||||
* should instead use the copy constructor, but for now this lets us build
|
||||
* with clang. See bug 689066 and llvm.org/pr11003 for the details.
|
||||
* Note: We can probably remove MoveRef completely once we are comfortable
|
||||
* using c++11.
|
||||
*/
|
||||
operator T&& () const { return static_cast<T&&>(*pointer); }
|
||||
#else
|
||||
operator T& () const { return *pointer; }
|
||||
#endif
|
||||
private:
|
||||
T *pointer;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
MoveRef<T> Move(T &t) { return MoveRef<T>(t); }
|
||||
|
||||
template<typename T>
|
||||
MoveRef<T> Move(const T &t) { return MoveRef<T>(const_cast<T &>(t)); }
|
||||
|
||||
/* Useful for implementing containers that assert non-reentrancy */
|
||||
class ReentrancyGuard
|
||||
{
|
||||
/* ReentrancyGuard is not copyable. */
|
||||
ReentrancyGuard(const ReentrancyGuard &);
|
||||
void operator=(const ReentrancyGuard &);
|
||||
|
||||
#ifdef DEBUG
|
||||
bool &entered;
|
||||
#endif
|
||||
public:
|
||||
template <class T>
|
||||
#ifdef DEBUG
|
||||
ReentrancyGuard(T &obj)
|
||||
: entered(obj.entered)
|
||||
#else
|
||||
ReentrancyGuard(T &/*obj*/)
|
||||
#endif
|
||||
{
|
||||
#ifdef DEBUG
|
||||
JS_ASSERT(!entered);
|
||||
entered = true;
|
||||
#endif
|
||||
}
|
||||
~ReentrancyGuard()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
entered = false;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Round x up to the nearest power of 2. This function assumes that the most
|
||||
* significant bit of x is not set, which would lead to overflow.
|
||||
*/
|
||||
JS_ALWAYS_INLINE size_t
|
||||
RoundUpPow2(size_t x)
|
||||
{
|
||||
return size_t(1) << JS_CEILING_LOG2W(x);
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
||||
/*
|
||||
* This signature is for malloc_usable_size-like functions used to measure
|
||||
* memory usage. A return value of zero indicates that the size is unknown,
|
||||
* and so a fall-back computation should be done for the size.
|
||||
*/
|
||||
typedef size_t(*JSUsableSizeFun)(void *p);
|
||||
|
||||
/* sixgill annotation defines */
|
||||
#ifndef HAVE_STATIC_ANNOTATIONS
|
||||
# define HAVE_STATIC_ANNOTATIONS
|
||||
# ifdef XGILL_PLUGIN
|
||||
# define STATIC_PRECONDITION(COND) __attribute__((precondition(#COND)))
|
||||
# define STATIC_PRECONDITION_ASSUME(COND) __attribute__((precondition_assume(#COND)))
|
||||
# define STATIC_POSTCONDITION(COND) __attribute__((postcondition(#COND)))
|
||||
# define STATIC_POSTCONDITION_ASSUME(COND) __attribute__((postcondition_assume(#COND)))
|
||||
# define STATIC_INVARIANT(COND) __attribute__((invariant(#COND)))
|
||||
# define STATIC_INVARIANT_ASSUME(COND) __attribute__((invariant_assume(#COND)))
|
||||
# define STATIC_PASTE2(X,Y) X ## Y
|
||||
# define STATIC_PASTE1(X,Y) STATIC_PASTE2(X,Y)
|
||||
# define STATIC_ASSERT(COND) \
|
||||
JS_BEGIN_MACRO \
|
||||
__attribute__((assert_static(#COND), unused)) \
|
||||
int STATIC_PASTE1(assert_static_, __COUNTER__); \
|
||||
JS_END_MACRO
|
||||
# define STATIC_ASSUME(COND) \
|
||||
JS_BEGIN_MACRO \
|
||||
__attribute__((assume_static(#COND), unused)) \
|
||||
int STATIC_PASTE1(assume_static_, __COUNTER__); \
|
||||
JS_END_MACRO
|
||||
# define STATIC_ASSERT_RUNTIME(COND) \
|
||||
JS_BEGIN_MACRO \
|
||||
__attribute__((assert_static_runtime(#COND), unused)) \
|
||||
int STATIC_PASTE1(assert_static_runtime_, __COUNTER__); \
|
||||
JS_END_MACRO
|
||||
# else /* XGILL_PLUGIN */
|
||||
# define STATIC_PRECONDITION(COND) /* nothing */
|
||||
# define STATIC_PRECONDITION_ASSUME(COND) /* nothing */
|
||||
# define STATIC_POSTCONDITION(COND) /* nothing */
|
||||
# define STATIC_POSTCONDITION_ASSUME(COND) /* nothing */
|
||||
# define STATIC_INVARIANT(COND) /* nothing */
|
||||
# define STATIC_INVARIANT_ASSUME(COND) /* nothing */
|
||||
# define STATIC_ASSERT(COND) JS_BEGIN_MACRO /* nothing */ JS_END_MACRO
|
||||
# define STATIC_ASSUME(COND) JS_BEGIN_MACRO /* nothing */ JS_END_MACRO
|
||||
# define STATIC_ASSERT_RUNTIME(COND) JS_BEGIN_MACRO /* nothing */ JS_END_MACRO
|
||||
# endif /* XGILL_PLUGIN */
|
||||
# define STATIC_SKIP_INFERENCE STATIC_INVARIANT(skip_inference())
|
||||
#endif /* HAVE_STATIC_ANNOTATIONS */
|
||||
|
||||
#endif /* js_utility_h__ */
|
@ -41,10 +41,8 @@
|
||||
#ifndef jsvector_h_
|
||||
#define jsvector_h_
|
||||
|
||||
#include "jsalloc.h"
|
||||
#include "jstl.h"
|
||||
#include "jsprvtd.h"
|
||||
#include "jsutil.h"
|
||||
#include "TemplateLib.h"
|
||||
#include "Utility.h"
|
||||
|
||||
/* Silence dire "bugs in previous versions of MSVC have been fixed" warnings */
|
||||
#ifdef _MSC_VER
|
||||
@ -54,6 +52,9 @@
|
||||
|
||||
namespace js {
|
||||
|
||||
template <class T, size_t N, class AllocPolicy>
|
||||
class Vector;
|
||||
|
||||
/*
|
||||
* This template class provides a default implementation for vector operations
|
||||
* when the element type is not known to be a POD, as judged by IsPodType.
|
@ -95,7 +95,13 @@ endif
|
||||
FORCE_STATIC_LIB = 1
|
||||
DIST_INSTALL = 1
|
||||
|
||||
VPATH = $(srcdir)
|
||||
VPATH = \
|
||||
$(srcdir) \
|
||||
$(srcdir)/builtin \
|
||||
$(srcdir)/ds \
|
||||
$(srcdir)/frontend \
|
||||
$(srcdir)/vm \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
jsalloc.cpp \
|
||||
@ -177,7 +183,6 @@ INSTALLED_HEADERS = \
|
||||
jsalloc.h \
|
||||
jsapi.h \
|
||||
jsatom.h \
|
||||
jsbit.h \
|
||||
jsclass.h \
|
||||
jsclist.h \
|
||||
jsclone.h \
|
||||
@ -217,9 +222,6 @@ INSTALLED_HEADERS = \
|
||||
jstypedarray.h \
|
||||
jstypes.h \
|
||||
jsutil.h \
|
||||
jsvector.h \
|
||||
jstl.h \
|
||||
jshashtable.h \
|
||||
jsversion.h \
|
||||
jswrapper.h \
|
||||
jsxdrapi.h \
|
||||
@ -228,16 +230,10 @@ INSTALLED_HEADERS = \
|
||||
$(NULL)
|
||||
|
||||
######################################################
|
||||
# BEGIN include sources for the engine subdirectories
|
||||
# BEGIN exported headers that are only exported
|
||||
# because of inclusion by an INSTALLED_HEADER
|
||||
#
|
||||
VPATH += \
|
||||
$(srcdir)/builtin \
|
||||
$(srcdir)/ds \
|
||||
$(srcdir)/frontend \
|
||||
$(srcdir)/vm \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS_NAMESPACES = vm ds
|
||||
EXPORTS_NAMESPACES += vm ds
|
||||
|
||||
EXPORTS_vm = \
|
||||
String.h \
|
||||
@ -246,7 +242,28 @@ EXPORTS_vm = \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS_ds = \
|
||||
LifoAlloc.h
|
||||
LifoAlloc.h \
|
||||
$(NULL)
|
||||
|
||||
######################################################
|
||||
# BEGIN include exported headers from the JS engine
|
||||
#
|
||||
# Ultimately, after cleansing INSTALLED_HEADERS,
|
||||
# these will be the ONLY headers exported by
|
||||
# the js engine
|
||||
#
|
||||
VPATH += \
|
||||
$(srcdir)/../public \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS_NAMESPACES += js
|
||||
|
||||
EXPORTS_js = \
|
||||
HashTable.h \
|
||||
TemplateLib.h \
|
||||
Utility.h \
|
||||
Vector.h \
|
||||
$(NULL)
|
||||
|
||||
###############################################
|
||||
# BEGIN include sources for low-level code shared with Gecko
|
||||
@ -259,9 +276,9 @@ EXPORTS_NAMESPACES += mozilla
|
||||
|
||||
EXPORTS_mozilla = \
|
||||
RangedPtr.h \
|
||||
RefPtr.h \
|
||||
Types.h \
|
||||
Util.h \
|
||||
RefPtr.h \
|
||||
Types.h \
|
||||
Util.h \
|
||||
$(NULL)
|
||||
|
||||
ifdef ENABLE_TRACEJIT
|
||||
|
@ -37,7 +37,7 @@
|
||||
#include "AssemblerBuffer.h"
|
||||
#include "jsstdint.h"
|
||||
#include "assembler/wtf/Assertions.h"
|
||||
#include "jsvector.h"
|
||||
#include "js/Vector.h"
|
||||
|
||||
#include "methodjit/Logging.h"
|
||||
#define IPFX " %s"
|
||||
|
@ -28,13 +28,14 @@
|
||||
|
||||
#include <stddef.h> // for ptrdiff_t
|
||||
#include <limits>
|
||||
#include "assembler/wtf/Assertions.h"
|
||||
|
||||
#include "jsalloc.h"
|
||||
#include "jsapi.h"
|
||||
#include "jshashtable.h"
|
||||
#include "jsprvtd.h"
|
||||
#include "jsvector.h"
|
||||
#include "jslock.h"
|
||||
|
||||
#include "assembler/wtf/Assertions.h"
|
||||
#include "js/HashTable.h"
|
||||
#include "js/Vector.h"
|
||||
|
||||
#if WTF_CPU_SPARC
|
||||
#ifdef linux // bugzilla 502369
|
||||
|
@ -39,7 +39,6 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "jsinfer.h"
|
||||
#include "jstl.h"
|
||||
|
||||
#include "builtin/RegExp.h"
|
||||
|
||||
|
@ -41,10 +41,11 @@
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "jsapi.h"
|
||||
#include "jshashtable.h"
|
||||
#include "prlink.h"
|
||||
#include "ffi.h"
|
||||
|
||||
#include "js/HashTable.h"
|
||||
|
||||
namespace js {
|
||||
namespace ctypes {
|
||||
|
||||
|
@ -41,7 +41,7 @@
|
||||
#ifndef InlineMap_h__
|
||||
#define InlineMap_h__
|
||||
|
||||
#include "jshashtable.h"
|
||||
#include "js/HashTable.h"
|
||||
|
||||
namespace js {
|
||||
|
@ -49,7 +49,8 @@
|
||||
*/
|
||||
|
||||
#include "jsutil.h"
|
||||
#include "jstl.h"
|
||||
|
||||
#include "js/TemplateLib.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
|
@ -41,9 +41,8 @@
|
||||
#ifndef ParseMaps_h__
|
||||
#define ParseMaps_h__
|
||||
|
||||
#include "jsvector.h"
|
||||
|
||||
#include "mfbt/InlineMap.h"
|
||||
#include "ds/InlineMap.h"
|
||||
#include "js/HashTable.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
|
@ -45,9 +45,9 @@
|
||||
#include "jscntxt.h"
|
||||
#include "jsinfer.h"
|
||||
#include "jsscript.h"
|
||||
#include "jstl.h"
|
||||
|
||||
#include "ds/LifoAlloc.h"
|
||||
#include "js/TemplateLib.h"
|
||||
|
||||
struct JSScript;
|
||||
|
||||
|
@ -40,7 +40,10 @@
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jsprvtd.h"
|
||||
#include "jsvector.h"
|
||||
#include "jsalloc.h"
|
||||
|
||||
#include "js/Vector.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
@ -83,7 +83,6 @@
|
||||
#include "jstracer.h"
|
||||
#include "prmjtime.h"
|
||||
#include "jsstaticcheck.h"
|
||||
#include "jsvector.h"
|
||||
#include "jsweakmap.h"
|
||||
#include "jswrapper.h"
|
||||
#include "jstypedarray.h"
|
||||
@ -96,7 +95,6 @@
|
||||
#include "jsobjinlines.h"
|
||||
#include "jsscopeinlines.h"
|
||||
#include "jsscriptinlines.h"
|
||||
#include "assembler/wtf/Platform.h"
|
||||
|
||||
#include "vm/RegExpObject-inl.h"
|
||||
#include "vm/Stack-inl.h"
|
||||
|
@ -47,9 +47,10 @@
|
||||
#include <stdio.h>
|
||||
#include "js-config.h"
|
||||
#include "jspubtd.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsval.h"
|
||||
|
||||
#include "js/Utility.h"
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
/* JS::Value can store a full int32. */
|
||||
|
@ -1,258 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code, released
|
||||
* March 31, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/*
|
||||
* Lifetime-based fast allocation, inspired by much prior art, including
|
||||
* "Fast Allocation and Deallocation of Memory Based on Object Lifetimes"
|
||||
* David R. Hanson, Software -- Practice and Experience, Vol. 20(1).
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "jsalloc.h"
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsbit.h"
|
||||
#include "jsarena.h"
|
||||
#include "jsprvtd.h"
|
||||
|
||||
using namespace js;
|
||||
|
||||
/* If JSArena's length is a multiple of 8, that ensures its payload is 8-aligned. */
|
||||
JS_STATIC_ASSERT(sizeof(JSArena) % 8 == 0);
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_InitArenaPool(JSArenaPool *pool, const char *name, size_t size, size_t align)
|
||||
{
|
||||
/* Restricting ourselves to some simple alignments keeps things simple. */
|
||||
if (align == 1 || align == 2 || align == 4 || align == 8) {
|
||||
pool->mask = align - 1;
|
||||
} else {
|
||||
/* This shouldn't happen, but set pool->mask reasonably if it does. */
|
||||
JS_NOT_REACHED("JS_InitArenaPool: bad align");
|
||||
pool->mask = 7;
|
||||
}
|
||||
pool->first.next = NULL;
|
||||
/* pool->first is a zero-sized dummy arena that's never allocated from. */
|
||||
pool->first.base = pool->first.avail = pool->first.limit =
|
||||
JS_ARENA_ALIGN(pool, &pool->first + 1);
|
||||
pool->current = &pool->first;
|
||||
pool->arenasize = size;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void *)
|
||||
JS_ArenaAllocate(JSArenaPool *pool, size_t nb)
|
||||
{
|
||||
/*
|
||||
* Search pool from current forward till we find or make enough space.
|
||||
*
|
||||
* NB: subtract nb from a->limit in the loop condition, instead of adding
|
||||
* nb to a->avail, to avoid overflow (possible when running a 32-bit
|
||||
* program on a 64-bit system where the kernel maps the heap up against the
|
||||
* top of the 32-bit address space, see bug 279273). Note that this
|
||||
* necessitates a comparison between nb and a->limit that looks like a
|
||||
* (conceptual) type error but isn't.
|
||||
*/
|
||||
JS_ASSERT((nb & pool->mask) == 0);
|
||||
JSArena *a;
|
||||
/*
|
||||
* Comparing nb to a->limit looks like a (conceptual) type error, but it's
|
||||
* necessary to avoid wrap-around. Yuk.
|
||||
*/
|
||||
for (a = pool->current; nb > a->limit || a->avail > a->limit - nb; pool->current = a) {
|
||||
JSArena **ap = &a->next;
|
||||
if (!*ap) {
|
||||
/* Not enough space in pool, so we must malloc. */
|
||||
size_t gross = sizeof(JSArena) + JS_MAX(nb, pool->arenasize);
|
||||
a = (JSArena *) OffTheBooks::malloc_(gross);
|
||||
if (!a)
|
||||
return NULL;
|
||||
|
||||
a->next = NULL;
|
||||
a->base = a->avail = jsuword(a) + sizeof(JSArena);
|
||||
/*
|
||||
* Because malloc returns 8-aligned pointers and sizeof(JSArena) is
|
||||
* a multiple of 8, a->base will always be 8-aligned, which should
|
||||
* suffice for any valid pool.
|
||||
*/
|
||||
JS_ASSERT(a->base == JS_ARENA_ALIGN(pool, a->base));
|
||||
a->limit = (jsuword)a + gross;
|
||||
|
||||
*ap = a;
|
||||
continue;
|
||||
}
|
||||
a = *ap; /* move to next arena */
|
||||
}
|
||||
|
||||
void* p = (void *)a->avail;
|
||||
a->avail += nb;
|
||||
JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
|
||||
return p;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void *)
|
||||
JS_ArenaRealloc(JSArenaPool *pool, void *p, size_t size, size_t incr)
|
||||
{
|
||||
/* If we've called JS_ArenaRealloc, the new size must be bigger than pool->arenasize. */
|
||||
JS_ASSERT(size + incr > pool->arenasize);
|
||||
|
||||
/* Find the arena containing |p|. */
|
||||
JSArena *a;
|
||||
JSArena **ap = &pool->first.next;
|
||||
while (true) {
|
||||
a = *ap;
|
||||
if (JS_IS_IN_ARENA(a, p))
|
||||
break;
|
||||
JS_ASSERT(a != pool->current);
|
||||
ap = &a->next;
|
||||
}
|
||||
/* If we've called JS_ArenaRealloc, p must be at the start of an arena. */
|
||||
JS_ASSERT(a->base == jsuword(p));
|
||||
|
||||
size_t gross = sizeof(JSArena) + JS_ARENA_ALIGN(pool, size + incr);
|
||||
a = (JSArena *) OffTheBooks::realloc_(a, gross);
|
||||
if (!a)
|
||||
return NULL;
|
||||
|
||||
a->base = jsuword(a) + sizeof(JSArena);
|
||||
a->avail = a->limit = jsuword(a) + gross;
|
||||
/*
|
||||
* Because realloc returns 8-aligned pointers and sizeof(JSArena) is a
|
||||
* multiple of 8, a->base will always be 8-aligned, which should suffice
|
||||
* for any valid pool.
|
||||
*/
|
||||
JS_ASSERT(a->base == JS_ARENA_ALIGN(pool, a->base));
|
||||
|
||||
if (a != *ap) {
|
||||
/* realloc moved the allocation: update other pointers to a. */
|
||||
if (pool->current == *ap)
|
||||
pool->current = a;
|
||||
*ap = a;
|
||||
}
|
||||
|
||||
return (void *)a->base;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void *)
|
||||
JS_ArenaGrow(JSArenaPool *pool, void *p, size_t size, size_t incr)
|
||||
{
|
||||
void *newp;
|
||||
|
||||
/*
|
||||
* If p points to an oversized allocation, it owns an entire arena, so we
|
||||
* can simply realloc the arena.
|
||||
*/
|
||||
if (size > pool->arenasize)
|
||||
return JS_ArenaRealloc(pool, p, size, incr);
|
||||
|
||||
JS_ARENA_ALLOCATE(newp, pool, size + incr);
|
||||
if (newp)
|
||||
memcpy(newp, p, size);
|
||||
return newp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free tail arenas linked after head, which may not be the true list head.
|
||||
* Reset pool->current to point to head in case it pointed at a tail arena.
|
||||
*/
|
||||
static void
|
||||
FreeArenaList(JSArenaPool *pool, JSArena *head)
|
||||
{
|
||||
JSArena **ap, *a;
|
||||
|
||||
ap = &head->next;
|
||||
a = *ap;
|
||||
if (!a)
|
||||
return;
|
||||
|
||||
#ifdef DEBUG
|
||||
do {
|
||||
JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
|
||||
a->avail = a->base;
|
||||
JS_CLEAR_UNUSED(a);
|
||||
} while ((a = a->next) != NULL);
|
||||
a = *ap;
|
||||
#endif
|
||||
|
||||
do {
|
||||
*ap = a->next;
|
||||
JS_CLEAR_ARENA(a);
|
||||
UnwantedForeground::free_(a);
|
||||
} while ((a = *ap) != NULL);
|
||||
|
||||
pool->current = head;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_ArenaRelease(JSArenaPool *pool, char *mark)
|
||||
{
|
||||
JSArena *a;
|
||||
|
||||
for (a = &pool->first; a; a = a->next) {
|
||||
JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
|
||||
|
||||
if (JS_IS_IN_ARENA(a, mark)) {
|
||||
a->avail = JS_ARENA_ALIGN(pool, mark);
|
||||
JS_ASSERT(a->avail <= a->limit);
|
||||
FreeArenaList(pool, a);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_FreeArenaPool(JSArenaPool *pool)
|
||||
{
|
||||
FreeArenaList(pool, &pool->first);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_FinishArenaPool(JSArenaPool *pool)
|
||||
{
|
||||
FreeArenaList(pool, &pool->first);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_ArenaFinish()
|
||||
{
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_ArenaShutDown(void)
|
||||
{
|
||||
}
|
@ -109,7 +109,6 @@
|
||||
#include "jsapi.h"
|
||||
#include "jsarray.h"
|
||||
#include "jsatom.h"
|
||||
#include "jsbit.h"
|
||||
#include "jsbool.h"
|
||||
#include "jsbuiltins.h"
|
||||
#include "jscntxt.h"
|
||||
@ -126,7 +125,6 @@
|
||||
#include "jsstr.h"
|
||||
#include "jsstaticcheck.h"
|
||||
#include "jstracer.h"
|
||||
#include "jsvector.h"
|
||||
#include "jswrapper.h"
|
||||
#include "methodjit/MethodJIT.h"
|
||||
#include "methodjit/StubCalls.h"
|
||||
|
@ -52,7 +52,6 @@
|
||||
#include "jsprf.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsatom.h"
|
||||
#include "jsbit.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsgc.h"
|
||||
#include "jsgcmark.h"
|
||||
|
@ -42,13 +42,14 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include "jsversion.h"
|
||||
#include "jsalloc.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsprvtd.h"
|
||||
#include "jshash.h"
|
||||
#include "jshashtable.h"
|
||||
#include "jspubtd.h"
|
||||
#include "jslock.h"
|
||||
|
||||
#include "js/HashTable.h"
|
||||
#include "vm/String.h"
|
||||
|
||||
/* Engine-internal extensions of jsid */
|
||||
|
305
js/src/jsbit.h
305
js/src/jsbit.h
@ -1,305 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code, released
|
||||
* March 31, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef jsbit_h___
|
||||
#define jsbit_h___
|
||||
|
||||
#include "jstypes.h"
|
||||
#include "jscompat.h"
|
||||
#include "jsutil.h"
|
||||
|
||||
JS_BEGIN_EXTERN_C
|
||||
|
||||
/*
|
||||
** A jsbitmap_t is a long integer that can be used for bitmaps
|
||||
*/
|
||||
typedef jsuword jsbitmap_t; /* NSPR name, a la Unix system types */
|
||||
typedef jsbitmap_t jsbitmap; /* JS-style scalar typedef name */
|
||||
|
||||
#define JS_BITMAP_SIZE(bits) (JS_HOWMANY(bits, JS_BITS_PER_WORD) * \
|
||||
sizeof(jsbitmap))
|
||||
|
||||
#define JS_TEST_BIT(_map,_bit) ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] & \
|
||||
((jsbitmap)1<<((_bit)&(JS_BITS_PER_WORD-1))))
|
||||
#define JS_SET_BIT(_map,_bit) ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] |= \
|
||||
((jsbitmap)1<<((_bit)&(JS_BITS_PER_WORD-1))))
|
||||
#define JS_CLEAR_BIT(_map,_bit) ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] &= \
|
||||
~((jsbitmap)1<<((_bit)&(JS_BITS_PER_WORD-1))))
|
||||
|
||||
/*
|
||||
** Compute the log of the least power of 2 greater than or equal to n
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSIntn) JS_CeilingLog2(JSUint32 i);
|
||||
|
||||
/*
|
||||
** Compute the log of the greatest power of 2 less than or equal to n
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSIntn) JS_FloorLog2(JSUint32 i);
|
||||
|
||||
/*
|
||||
* Replace bit-scanning code sequences with CPU-specific instructions to
|
||||
* speedup calculations of ceiling/floor log2.
|
||||
*
|
||||
* With GCC 3.4 or later we can use __builtin_clz for that, see bug 327129.
|
||||
*
|
||||
* SWS: Added MSVC intrinsic bitscan support. See bugs 349364 and 356856.
|
||||
*/
|
||||
#if defined(_WIN32) && (_MSC_VER >= 1300) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
|
||||
|
||||
unsigned char _BitScanForward(unsigned long * Index, unsigned long Mask);
|
||||
unsigned char _BitScanReverse(unsigned long * Index, unsigned long Mask);
|
||||
# pragma intrinsic(_BitScanForward,_BitScanReverse)
|
||||
|
||||
__forceinline static int
|
||||
__BitScanForward32(unsigned int val)
|
||||
{
|
||||
unsigned long idx;
|
||||
|
||||
_BitScanForward(&idx, (unsigned long)val);
|
||||
return (int)idx;
|
||||
}
|
||||
__forceinline static int
|
||||
__BitScanReverse32(unsigned int val)
|
||||
{
|
||||
unsigned long idx;
|
||||
|
||||
_BitScanReverse(&idx, (unsigned long)val);
|
||||
return (int)(31-idx);
|
||||
}
|
||||
# define js_bitscan_ctz32(val) __BitScanForward32(val)
|
||||
# define js_bitscan_clz32(val) __BitScanReverse32(val)
|
||||
# define JS_HAS_BUILTIN_BITSCAN32
|
||||
|
||||
#if defined(_M_AMD64) || defined(_M_X64)
|
||||
unsigned char _BitScanForward64(unsigned long * Index, unsigned __int64 Mask);
|
||||
unsigned char _BitScanReverse64(unsigned long * Index, unsigned __int64 Mask);
|
||||
# pragma intrinsic(_BitScanForward64,_BitScanReverse64)
|
||||
|
||||
__forceinline static int
|
||||
__BitScanForward64(unsigned __int64 val)
|
||||
{
|
||||
unsigned long idx;
|
||||
|
||||
_BitScanForward64(&idx, val);
|
||||
return (int)idx;
|
||||
}
|
||||
__forceinline static int
|
||||
__BitScanReverse64(unsigned __int64 val)
|
||||
{
|
||||
unsigned long idx;
|
||||
|
||||
_BitScanReverse64(&idx, val);
|
||||
return (int)(63-idx);
|
||||
}
|
||||
# define js_bitscan_ctz64(val) __BitScanForward64(val)
|
||||
# define js_bitscan_clz64(val) __BitScanReverse64(val)
|
||||
# define JS_HAS_BUILTIN_BITSCAN64
|
||||
#endif
|
||||
#elif (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
|
||||
|
||||
# define js_bitscan_ctz32(val) __builtin_ctz(val)
|
||||
# define js_bitscan_clz32(val) __builtin_clz(val)
|
||||
# define JS_HAS_BUILTIN_BITSCAN32
|
||||
# if (JS_BYTES_PER_WORD == 8)
|
||||
# define js_bitscan_ctz64(val) __builtin_ctzll(val)
|
||||
# define js_bitscan_clz64(val) __builtin_clzll(val)
|
||||
# define JS_HAS_BUILTIN_BITSCAN64
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Macro version of JS_CeilingLog2: Compute the log of the least power of
|
||||
** 2 greater than or equal to _n. The result is returned in _log2.
|
||||
*/
|
||||
#ifdef JS_HAS_BUILTIN_BITSCAN32
|
||||
/*
|
||||
* Use intrinsic function or count-leading-zeros to calculate ceil(log2(_n)).
|
||||
* The macro checks for "n <= 1" and not "n != 0" as js_bitscan_clz32(0) is
|
||||
* undefined.
|
||||
*/
|
||||
# define JS_CEILING_LOG2(_log2,_n) \
|
||||
JS_BEGIN_MACRO \
|
||||
unsigned int j_ = (unsigned int)(_n); \
|
||||
(_log2) = (j_ <= 1 ? 0 : 32 - js_bitscan_clz32(j_ - 1)); \
|
||||
JS_END_MACRO
|
||||
#else
|
||||
# define JS_CEILING_LOG2(_log2,_n) \
|
||||
JS_BEGIN_MACRO \
|
||||
JSUint32 j_ = (JSUint32)(_n); \
|
||||
(_log2) = 0; \
|
||||
if ((j_) & ((j_)-1)) \
|
||||
(_log2) += 1; \
|
||||
if ((j_) >> 16) \
|
||||
(_log2) += 16, (j_) >>= 16; \
|
||||
if ((j_) >> 8) \
|
||||
(_log2) += 8, (j_) >>= 8; \
|
||||
if ((j_) >> 4) \
|
||||
(_log2) += 4, (j_) >>= 4; \
|
||||
if ((j_) >> 2) \
|
||||
(_log2) += 2, (j_) >>= 2; \
|
||||
if ((j_) >> 1) \
|
||||
(_log2) += 1; \
|
||||
JS_END_MACRO
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Macro version of JS_FloorLog2: Compute the log of the greatest power of
|
||||
** 2 less than or equal to _n. The result is returned in _log2.
|
||||
**
|
||||
** This is equivalent to finding the highest set bit in the word.
|
||||
*/
|
||||
#ifdef JS_HAS_BUILTIN_BITSCAN32
|
||||
/*
|
||||
* Use js_bitscan_clz32 or count-leading-zeros to calculate floor(log2(_n)).
|
||||
* Since js_bitscan_clz32(0) is undefined, the macro set the loweset bit to 1
|
||||
* to ensure 0 result when _n == 0.
|
||||
*/
|
||||
# define JS_FLOOR_LOG2(_log2,_n) \
|
||||
JS_BEGIN_MACRO \
|
||||
(_log2) = 31 - js_bitscan_clz32(((unsigned int)(_n)) | 1); \
|
||||
JS_END_MACRO
|
||||
#else
|
||||
# define JS_FLOOR_LOG2(_log2,_n) \
|
||||
JS_BEGIN_MACRO \
|
||||
JSUint32 j_ = (JSUint32)(_n); \
|
||||
(_log2) = 0; \
|
||||
if ((j_) >> 16) \
|
||||
(_log2) += 16, (j_) >>= 16; \
|
||||
if ((j_) >> 8) \
|
||||
(_log2) += 8, (j_) >>= 8; \
|
||||
if ((j_) >> 4) \
|
||||
(_log2) += 4, (j_) >>= 4; \
|
||||
if ((j_) >> 2) \
|
||||
(_log2) += 2, (j_) >>= 2; \
|
||||
if ((j_) >> 1) \
|
||||
(_log2) += 1; \
|
||||
JS_END_MACRO
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Internal function.
|
||||
* Compute the log of the least power of 2 greater than or equal to n. This is
|
||||
* a version of JS_CeilingLog2 that operates on unsigned integers with
|
||||
* CPU-dependant size.
|
||||
*/
|
||||
#define JS_CEILING_LOG2W(n) ((n) <= 1 ? 0 : 1 + JS_FLOOR_LOG2W((n) - 1))
|
||||
|
||||
/*
|
||||
* Internal function.
|
||||
* Compute the log of the greatest power of 2 less than or equal to n.
|
||||
* This is a version of JS_FloorLog2 that operates on unsigned integers with
|
||||
* CPU-dependant size and requires that n != 0.
|
||||
*/
|
||||
#define JS_FLOOR_LOG2W(n) (JS_ASSERT((n) != 0), js_FloorLog2wImpl(n))
|
||||
|
||||
#if JS_BYTES_PER_WORD == 4
|
||||
|
||||
# ifdef JS_HAS_BUILTIN_BITSCAN32
|
||||
# define js_FloorLog2wImpl(n) \
|
||||
((size_t)(JS_BITS_PER_WORD - 1 - js_bitscan_clz32(n)))
|
||||
# else
|
||||
# define js_FloorLog2wImpl(n) ((size_t)JS_FloorLog2(n))
|
||||
#endif
|
||||
|
||||
#elif JS_BYTES_PER_WORD == 8
|
||||
|
||||
# ifdef JS_HAS_BUILTIN_BITSCAN64
|
||||
# define js_FloorLog2wImpl(n) \
|
||||
((size_t)(JS_BITS_PER_WORD - 1 - js_bitscan_clz64(n)))
|
||||
# else
|
||||
extern size_t js_FloorLog2wImpl(size_t n);
|
||||
# endif
|
||||
|
||||
#else
|
||||
|
||||
# error "NOT SUPPORTED"
|
||||
|
||||
#endif
|
||||
|
||||
namespace js {
|
||||
|
||||
inline size_t
|
||||
CountTrailingZeros(size_t n)
|
||||
{
|
||||
JS_ASSERT(n != 0);
|
||||
#if JS_BYTES_PER_WORD != 4 && JS_BYTES_PER_WORD != 8
|
||||
# error "NOT SUPPORTED"
|
||||
#endif
|
||||
|
||||
#if JS_BYTES_PER_WORD == 4 && defined JS_HAS_BUILTIN_BITSCAN32
|
||||
return js_bitscan_ctz32(n);
|
||||
#elif JS_BYTES_PER_WORD == 8 && defined JS_HAS_BUILTIN_BITSCAN64
|
||||
return js_bitscan_ctz64(n);
|
||||
#else
|
||||
size_t count = 0;
|
||||
# if JS_BYTES_PER_WORD == 8
|
||||
if (!(n & size_t(0xFFFFFFFFU))) { count += 32; n >>= 32; }
|
||||
# endif
|
||||
if (!(n & 0xFFFF)) { count += 16; n >>= 16; }
|
||||
if (!(n & 0xFF)) { count += 8; n >>= 8; }
|
||||
if (!(n & 0xF)) { count += 4; n >>= 4; }
|
||||
if (!(n & 0x3)) { count += 2; n >>= 2; }
|
||||
if (!(n & 0x1)) { count += 1; n >>= 1; }
|
||||
return count + 1 - (n & 0x1);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Macros for rotate left. There is no rotate operation in the C Language so
|
||||
* the construct (a << 4) | (a >> 28) is used instead. Most compilers convert
|
||||
* this to a rotate instruction but some versions of MSVC don't without a
|
||||
* little help. To get MSVC to generate a rotate instruction, we have to use
|
||||
* the _rotl intrinsic and use a pragma to make _rotl inline.
|
||||
*
|
||||
* MSVC in VS2005 will do an inline rotate instruction on the above construct.
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || \
|
||||
defined(_M_X64))
|
||||
#include <stdlib.h>
|
||||
#pragma intrinsic(_rotl)
|
||||
#define JS_ROTATE_LEFT32(a, bits) _rotl(a, bits)
|
||||
#else
|
||||
#define JS_ROTATE_LEFT32(a, bits) (((a) << (bits)) | ((a) >> (32 - (bits))))
|
||||
#endif
|
||||
|
||||
JS_END_EXTERN_C
|
||||
#endif /* jsbit_h___ */
|
@ -53,7 +53,6 @@
|
||||
#include "jsnum.h"
|
||||
#include "jsobj.h"
|
||||
#include "jsstr.h"
|
||||
#include "jsvector.h"
|
||||
|
||||
#include "vm/GlobalObject.h"
|
||||
|
||||
|
@ -58,7 +58,6 @@
|
||||
#include "jsstr.h"
|
||||
#include "jsbuiltins.h"
|
||||
#include "jstracer.h"
|
||||
#include "jsvector.h"
|
||||
|
||||
#include "jsatominlines.h"
|
||||
#include "jscntxtinlines.h"
|
||||
|
@ -41,9 +41,10 @@
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jshashtable.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsvector.h"
|
||||
|
||||
#include "js/HashTable.h"
|
||||
#include "js/Vector.h"
|
||||
|
||||
JS_FRIEND_API(uint64_t)
|
||||
js_GetSCOffset(JSStructuredCloneWriter* writer);
|
||||
|
@ -51,15 +51,15 @@
|
||||
#include "jsdhash.h"
|
||||
#include "jsgc.h"
|
||||
#include "jsgcchunk.h"
|
||||
#include "jshashtable.h"
|
||||
#include "jspropertycache.h"
|
||||
#include "jspropertytree.h"
|
||||
#include "jsstaticcheck.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsvector.h"
|
||||
#include "prmjtime.h"
|
||||
|
||||
#include "ds/LifoAlloc.h"
|
||||
#include "js/HashTable.h"
|
||||
#include "js/Vector.h"
|
||||
#include "vm/StackSpace.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
@ -49,7 +49,6 @@
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsclist.h"
|
||||
#include "jshashtable.h"
|
||||
#include "jsapi.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsversion.h"
|
||||
@ -69,6 +68,7 @@
|
||||
#include "jsstr.h"
|
||||
#include "jswatchpoint.h"
|
||||
#include "jswrapper.h"
|
||||
|
||||
#include "vm/Debugger.h"
|
||||
|
||||
#include "jsatominlines.h"
|
||||
|
@ -45,7 +45,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "jsstdint.h"
|
||||
#include "jsbit.h"
|
||||
#include "jsdhash.h"
|
||||
#include "jsutil.h"
|
||||
|
||||
|
@ -47,7 +47,6 @@
|
||||
#include "jsapi.h"
|
||||
#include "jsprvtd.h"
|
||||
#include "jsnum.h"
|
||||
#include "jsbit.h"
|
||||
#include "jslibmath.h"
|
||||
#include "jscntxt.h"
|
||||
|
||||
|
@ -49,7 +49,6 @@
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsbit.h"
|
||||
#include "jsprf.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsatom.h"
|
||||
@ -7775,13 +7774,6 @@ js_FinishTakingSrcNotes(JSContext *cx, JSCodeGenerator *cg, jssrcnote *notes)
|
||||
memcpy(notes + prologCount, cg->main.notes, SRCNOTE_SIZE(mainCount));
|
||||
SN_MAKE_TERMINATOR(¬es[totalCount]);
|
||||
|
||||
#ifdef DEBUG_notme
|
||||
{ int bin = JS_CeilingLog2(totalCount);
|
||||
if (bin >= NBINS)
|
||||
bin = NBINS - 1;
|
||||
++hist[bin];
|
||||
}
|
||||
#endif
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,6 @@
|
||||
#include <string.h>
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsbit.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsprf.h"
|
||||
#include "jsapi.h"
|
||||
@ -618,8 +617,8 @@ StackTraceToString(JSContext *cx, JSExnPrivate *priv)
|
||||
length_ >= STACK_LENGTH_LIMIT - stacklen) { \
|
||||
goto done; \
|
||||
} \
|
||||
stackmax = JS_BIT(JS_CeilingLog2(stacklen + length_)); \
|
||||
ptr_ = cx->realloc_(stackbuf, (stackmax+1) * sizeof(jschar)); \
|
||||
stackmax = RoundUpPow2(stacklen + length_); \
|
||||
ptr_ = cx->realloc_(stackbuf, (stackmax+1) * sizeof(jschar)); \
|
||||
if (!ptr_) \
|
||||
goto bad; \
|
||||
stackbuf = (jschar *) ptr_; \
|
||||
|
@ -44,7 +44,6 @@
|
||||
#include <string.h>
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsbit.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsarray.h"
|
||||
|
@ -54,7 +54,6 @@
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
#include "jshash.h"
|
||||
#include "jsbit.h"
|
||||
#include "jsclist.h"
|
||||
#include "jsprf.h"
|
||||
#include "jsapi.h"
|
||||
@ -70,7 +69,6 @@
|
||||
#include "jsgc.h"
|
||||
#include "jsgcchunk.h"
|
||||
#include "jsgcmark.h"
|
||||
#include "jshashtable.h"
|
||||
#include "jsinterp.h"
|
||||
#include "jsiter.h"
|
||||
#include "jslock.h"
|
||||
@ -89,13 +87,13 @@
|
||||
#endif
|
||||
|
||||
#include "methodjit/MethodJIT.h"
|
||||
#include "vm/String.h"
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/String.h"
|
||||
|
||||
#include "jsobjinlines.h"
|
||||
|
||||
#include "vm/String-inl.h"
|
||||
#include "vm/CallObject-inl.h"
|
||||
#include "vm/String-inl.h"
|
||||
|
||||
#ifdef MOZ_VALGRIND
|
||||
# define JS_VALGRIND
|
||||
|
@ -45,20 +45,21 @@
|
||||
*/
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "jsalloc.h"
|
||||
#include "jstypes.h"
|
||||
#include "jsprvtd.h"
|
||||
#include "jspubtd.h"
|
||||
#include "jsdhash.h"
|
||||
#include "jsbit.h"
|
||||
#include "jsgcchunk.h"
|
||||
#include "jshashtable.h"
|
||||
#include "jslock.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsvector.h"
|
||||
#include "jsversion.h"
|
||||
#include "jsgcstats.h"
|
||||
#include "jscell.h"
|
||||
|
||||
#include "js/HashTable.h"
|
||||
#include "js/Vector.h"
|
||||
|
||||
struct JSCompartment;
|
||||
|
||||
extern "C" void
|
||||
|
@ -43,11 +43,11 @@
|
||||
#include "jsgc.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jscompartment.h"
|
||||
#include "jslock.h"
|
||||
#include "jsscope.h"
|
||||
#include "jsxml.h"
|
||||
|
||||
#include "jslock.h"
|
||||
#include "jstl.h"
|
||||
#include "js/TemplateLib.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
|
@ -43,9 +43,10 @@
|
||||
#include "jsgc.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jscompartment.h"
|
||||
|
||||
#include "jslock.h"
|
||||
#include "jstl.h"
|
||||
|
||||
|
||||
#include "js/TemplateLib.h"
|
||||
|
||||
namespace js {
|
||||
namespace gc {
|
||||
|
@ -44,7 +44,6 @@
|
||||
#include <string.h>
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsbit.h"
|
||||
#include "jsutil.h"
|
||||
#include "jshash.h"
|
||||
|
||||
@ -107,7 +106,7 @@ JS_NewHashTable(uint32 n, JSHashFunction keyHash,
|
||||
if (n <= MINBUCKETS) {
|
||||
n = MINBUCKETSLOG2;
|
||||
} else {
|
||||
n = JS_CeilingLog2(n);
|
||||
n = JS_CEILING_LOG2W(n);
|
||||
if ((int32)n < 0)
|
||||
return NULL;
|
||||
}
|
||||
@ -387,7 +386,7 @@ out:
|
||||
JS_ASSERT(ht->nentries < nlimit);
|
||||
nbuckets = NBUCKETS(ht);
|
||||
if (MINBUCKETS < nbuckets && ht->nentries < UNDERLOADED(nbuckets)) {
|
||||
newlog2 = JS_CeilingLog2(ht->nentries);
|
||||
newlog2 = JS_CEILING_LOG2W(ht->nentries);
|
||||
if (newlog2 < MINBUCKETSLOG2)
|
||||
newlog2 = MINBUCKETSLOG2;
|
||||
|
||||
|
@ -39,7 +39,6 @@
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jsautooplen.h"
|
||||
#include "jsbit.h"
|
||||
#include "jsbool.h"
|
||||
#include "jsdate.h"
|
||||
#include "jsexn.h"
|
||||
@ -55,7 +54,6 @@
|
||||
#include "jsscan.h"
|
||||
#include "jsscope.h"
|
||||
#include "jsstr.h"
|
||||
#include "jstl.h"
|
||||
#include "jsiter.h"
|
||||
|
||||
#include "methodjit/MethodJIT.h"
|
||||
|
@ -45,11 +45,10 @@
|
||||
#include "jsalloc.h"
|
||||
#include "jscell.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "jstl.h"
|
||||
#include "jsprvtd.h"
|
||||
#include "jshashtable.h"
|
||||
|
||||
#include "ds/LifoAlloc.h"
|
||||
#include "js/HashTable.h"
|
||||
|
||||
namespace js {
|
||||
namespace types {
|
||||
|
@ -73,7 +73,7 @@
|
||||
#include "jsstaticcheck.h"
|
||||
#include "jstracer.h"
|
||||
#include "jslibmath.h"
|
||||
#include "jsvector.h"
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
#include "methodjit/MethodJIT.h"
|
||||
#include "methodjit/MethodJIT-inl.h"
|
||||
@ -2730,7 +2730,7 @@ BEGIN_CASE(JSOP_BINDNAME)
|
||||
END_CASE(JSOP_BINDNAME)
|
||||
|
||||
BEGIN_CASE(JSOP_IMACOP)
|
||||
JS_ASSERT(JS_UPTRDIFF(regs.fp()->imacropc(), script->code) < script->length);
|
||||
JS_ASSERT(UnsignedPtrDiff(regs.fp()->imacropc(), script->code) < script->length);
|
||||
op = JSOp(*regs.fp()->imacropc());
|
||||
DO_OP();
|
||||
|
||||
|
@ -56,7 +56,6 @@
|
||||
#include "jsfun.h"
|
||||
#include "jsgc.h"
|
||||
#include "jsgcmark.h"
|
||||
#include "jshashtable.h"
|
||||
#include "jsinterp.h"
|
||||
#include "jsiter.h"
|
||||
#include "jslock.h"
|
||||
@ -68,7 +67,6 @@
|
||||
#include "jsscope.h"
|
||||
#include "jsscript.h"
|
||||
#include "jsstaticcheck.h"
|
||||
#include "jsvector.h"
|
||||
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
#include "jsxml.h"
|
||||
|
@ -55,7 +55,6 @@
|
||||
#include "jsutil.h"
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsbit.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsgc.h"
|
||||
#include "jslock.h"
|
||||
@ -504,7 +503,7 @@ js_SetupLocks(int listc, int globc)
|
||||
if (globc > 100 || globc < 0) /* globc == number of global locks */
|
||||
printf("Bad number %d in js_SetupLocks()!\n", listc);
|
||||
#endif
|
||||
global_locks_log2 = JS_CeilingLog2(globc);
|
||||
global_locks_log2 = JS_CEILING_LOG2W(globc);
|
||||
global_locks_mask = JS_BITMASK(global_locks_log2);
|
||||
global_lock_count = JS_BIT(global_locks_log2);
|
||||
global_locks = (PRLock **) OffTheBooks::malloc_(global_lock_count * sizeof(PRLock*));
|
||||
|
@ -37,7 +37,6 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "jsstdint.h"
|
||||
#include "jsbit.h"
|
||||
#include "jsutil.h"
|
||||
|
||||
/*
|
||||
@ -55,31 +54,6 @@ JS_STATIC_ASSERT_IF(JS_BYTES_PER_WORD == 8,
|
||||
sizeof(unsigned long long) == sizeof(JSUword));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Compute the log of the least power of 2 greater than or equal to n
|
||||
*/
|
||||
JS_PUBLIC_API(JSIntn)
|
||||
JS_CeilingLog2(JSUint32 n)
|
||||
{
|
||||
JSIntn log2;
|
||||
|
||||
JS_CEILING_LOG2(log2, n);
|
||||
return log2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the log of the greatest power of 2 less than or equal to n.
|
||||
* This really just finds the highest set bit in the word.
|
||||
*/
|
||||
JS_PUBLIC_API(JSIntn)
|
||||
JS_FloorLog2(JSUint32 n)
|
||||
{
|
||||
JSIntn log2;
|
||||
|
||||
JS_FLOOR_LOG2(log2, n);
|
||||
return log2;
|
||||
}
|
||||
|
||||
/*
|
||||
* js_FloorLog2wImpl has to be defined only for 64-bit non-GCC case.
|
||||
*/
|
||||
|
@ -72,7 +72,6 @@
|
||||
#include "jsscope.h"
|
||||
#include "jsstr.h"
|
||||
#include "jstracer.h"
|
||||
#include "jsvector.h"
|
||||
#include "jslibmath.h"
|
||||
|
||||
#include "vm/GlobalObject.h"
|
||||
|
@ -45,7 +45,6 @@
|
||||
#include <string.h>
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsbit.h"
|
||||
#include "jsutil.h"
|
||||
#include "jshash.h"
|
||||
#include "jsdhash.h"
|
||||
|
@ -57,7 +57,6 @@
|
||||
#include "jspubtd.h"
|
||||
#include "jsprvtd.h"
|
||||
#include "jslock.h"
|
||||
#include "jsvector.h"
|
||||
#include "jscell.h"
|
||||
|
||||
#include "vm/String.h"
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include "jsiter.h"
|
||||
#include "jsnum.h"
|
||||
#include "jsobj.h"
|
||||
#include "json.h"
|
||||
#include "jsonparser.h"
|
||||
#include "jsprf.h"
|
||||
#include "jsscan.h"
|
||||
@ -58,9 +59,6 @@
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsxml.h"
|
||||
#include "jsvector.h"
|
||||
|
||||
#include "json.h"
|
||||
|
||||
#include "jsatominlines.h"
|
||||
#include "jsinferinlines.h"
|
||||
|
@ -40,7 +40,8 @@
|
||||
|
||||
#include "jsprvtd.h"
|
||||
#include "jspubtd.h"
|
||||
#include "jsvector.h"
|
||||
|
||||
#include "js/Vector.h"
|
||||
|
||||
#define JSON_MAX_DEPTH 2048
|
||||
#define JSON_PARSER_BUFSIZE 1024
|
||||
|
@ -68,7 +68,6 @@
|
||||
#include "jsscript.h"
|
||||
#include "jsstr.h"
|
||||
#include "jsstaticcheck.h"
|
||||
#include "jsvector.h"
|
||||
|
||||
#include "vm/Debugger.h"
|
||||
|
||||
@ -4100,7 +4099,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
||||
outer = jp->script;
|
||||
outerfun = jp->fun;
|
||||
outerLocalNames = jp->localNames;
|
||||
LOCAL_ASSERT(JS_UPTRDIFF(pc, outer->code) <= outer->length);
|
||||
LOCAL_ASSERT(UnsignedPtrDiff(pc, outer->code) <= outer->length);
|
||||
jp->script = inner;
|
||||
jp->fun = fun;
|
||||
jp->localNames = innerLocalNames;
|
||||
|
@ -95,9 +95,4 @@ typedef JSInt8 int8;
|
||||
|
||||
typedef JSFloat64 float64;
|
||||
|
||||
/* Re: jsbit.h */
|
||||
#define TEST_BIT JS_TEST_BIT
|
||||
#define SET_BIT JS_SET_BIT
|
||||
#define CLEAR_BIT JS_CLEAR_BIT
|
||||
|
||||
#endif /* !defined(PROTYPES_H) */
|
||||
|
@ -80,7 +80,6 @@
|
||||
#include "jsstr.h"
|
||||
#include "jsstaticcheck.h"
|
||||
#include "jslibmath.h"
|
||||
#include "jsvector.h"
|
||||
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
#include "jsxml.h"
|
||||
|
@ -1077,7 +1077,7 @@ struct JSFunctionBoxQueue {
|
||||
: vector(NULL), head(0), tail(0), lengthMask(0) { }
|
||||
|
||||
bool init(uint32 count) {
|
||||
lengthMask = JS_BITMASK(JS_CeilingLog2(count));
|
||||
lengthMask = JS_BITMASK(JS_CEILING_LOG2W(count));
|
||||
vector = (JSFunctionBox **) js::OffTheBooks::malloc_(sizeof(JSFunctionBox) * length());
|
||||
return !!vector;
|
||||
}
|
||||
|
@ -498,7 +498,7 @@ PropertyCache::purgeForScript(JSContext *cx, JSScript *script)
|
||||
JS_ASSERT(!cx->runtime->gcRunning);
|
||||
|
||||
for (PropertyCacheEntry *entry = table; entry < table + SIZE; entry++) {
|
||||
if (JS_UPTRDIFF(entry->kpc, script->code) < script->length) {
|
||||
if (UnsignedPtrDiff(entry->kpc, script->code) < script->length) {
|
||||
entry->kpc = NULL;
|
||||
#ifdef DEBUG
|
||||
entry->kshape = entry->vcap = 0;
|
||||
|
@ -40,9 +40,10 @@
|
||||
#ifndef jspropertytree_h___
|
||||
#define jspropertytree_h___
|
||||
|
||||
#include "jshashtable.h"
|
||||
#include "jsprvtd.h"
|
||||
|
||||
#include "js/HashTable.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
struct ShapeHasher {
|
||||
|
@ -47,11 +47,9 @@
|
||||
#include "jsobj.h"
|
||||
#include "jsreflect.h"
|
||||
#include "jscntxt.h" /* for jsparse.h */
|
||||
#include "jsbit.h" /* for jsparse.h */
|
||||
#include "jsscript.h" /* for jsparse.h */
|
||||
#include "jsinterp.h" /* for jsparse.h */
|
||||
#include "jsparse.h"
|
||||
#include "jsvector.h"
|
||||
#include "jsemit.h"
|
||||
#include "jsscan.h"
|
||||
#include "jsprf.h"
|
||||
|
@ -54,7 +54,6 @@
|
||||
#include <string.h>
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsbit.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsprf.h"
|
||||
#include "jsapi.h"
|
||||
@ -69,7 +68,6 @@
|
||||
#include "jsscan.h"
|
||||
#include "jsscript.h"
|
||||
#include "jsstaticcheck.h"
|
||||
#include "jsvector.h"
|
||||
|
||||
#include "vm/RegExpObject.h"
|
||||
|
||||
|
@ -51,7 +51,8 @@
|
||||
#include "jsopcode.h"
|
||||
#include "jsprvtd.h"
|
||||
#include "jspubtd.h"
|
||||
#include "jsvector.h"
|
||||
|
||||
#include "js/Vector.h"
|
||||
|
||||
#define JS_KEYWORD(keyword, type, op, version) \
|
||||
extern const char js_##keyword##_str[];
|
||||
|
@ -46,7 +46,6 @@
|
||||
#include <string.h>
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsbit.h"
|
||||
#include "jsclist.h"
|
||||
#include "jsdhash.h"
|
||||
#include "jsutil.h"
|
||||
@ -141,7 +140,7 @@ PropertyTable::init(JSRuntime *rt, Shape *lastProp)
|
||||
* event, let's try to grow, overallocating to hold at least twice the
|
||||
* current population.
|
||||
*/
|
||||
uint32 sizeLog2 = JS_CeilingLog2(2 * entryCount);
|
||||
uint32 sizeLog2 = JS_CEILING_LOG2W(2 * entryCount);
|
||||
if (sizeLog2 < MIN_SIZE_LOG2)
|
||||
sizeLog2 = MIN_SIZE_LOG2;
|
||||
|
||||
|
@ -52,12 +52,13 @@
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "jscompartment.h"
|
||||
#include "jshashtable.h"
|
||||
#include "jsobj.h"
|
||||
#include "jsprvtd.h"
|
||||
#include "jspubtd.h"
|
||||
#include "jspropertytree.h"
|
||||
|
||||
#include "js/HashTable.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4800)
|
||||
|
@ -40,86 +40,4 @@
|
||||
#ifndef jsstaticcheck_h___
|
||||
#define jsstaticcheck_h___
|
||||
|
||||
#ifdef NS_STATIC_CHECKING
|
||||
/*
|
||||
* Trigger a control flow check to make sure that code flows through label
|
||||
*/
|
||||
inline __attribute__ ((unused)) void MUST_FLOW_THROUGH(const char *label) {
|
||||
}
|
||||
|
||||
/* avoid unused goto-label warnings */
|
||||
#define MUST_FLOW_LABEL(label) goto label; label:
|
||||
|
||||
inline JS_FORCES_STACK void VOUCH_DOES_NOT_REQUIRE_STACK() {}
|
||||
|
||||
inline JS_FORCES_STACK void
|
||||
JS_ASSERT_NOT_ON_TRACE(JSContext *cx)
|
||||
{
|
||||
JS_ASSERT(!JS_ON_TRACE(cx));
|
||||
}
|
||||
|
||||
#else
|
||||
#define MUST_FLOW_THROUGH(label) ((void) 0)
|
||||
#define MUST_FLOW_LABEL(label)
|
||||
#define VOUCH_DOES_NOT_REQUIRE_STACK() ((void) 0)
|
||||
#define JS_ASSERT_NOT_ON_TRACE(cx) JS_ASSERT(!JS_ON_TRACE(cx))
|
||||
#endif
|
||||
#define VOUCH_HAVE_STACK VOUCH_DOES_NOT_REQUIRE_STACK
|
||||
|
||||
/* sixgill annotation defines */
|
||||
|
||||
/* Avoid name collision if included with other headers defining annotations. */
|
||||
#ifndef HAVE_STATIC_ANNOTATIONS
|
||||
#define HAVE_STATIC_ANNOTATIONS
|
||||
|
||||
#ifdef XGILL_PLUGIN
|
||||
|
||||
#define STATIC_PRECONDITION(COND) __attribute__((precondition(#COND)))
|
||||
#define STATIC_PRECONDITION_ASSUME(COND) __attribute__((precondition_assume(#COND)))
|
||||
#define STATIC_POSTCONDITION(COND) __attribute__((postcondition(#COND)))
|
||||
#define STATIC_POSTCONDITION_ASSUME(COND) __attribute__((postcondition_assume(#COND)))
|
||||
#define STATIC_INVARIANT(COND) __attribute__((invariant(#COND)))
|
||||
#define STATIC_INVARIANT_ASSUME(COND) __attribute__((invariant_assume(#COND)))
|
||||
|
||||
/* Used to make identifiers for assert/assume annotations in a function. */
|
||||
#define STATIC_PASTE2(X,Y) X ## Y
|
||||
#define STATIC_PASTE1(X,Y) STATIC_PASTE2(X,Y)
|
||||
|
||||
#define STATIC_ASSERT(COND) \
|
||||
JS_BEGIN_MACRO \
|
||||
__attribute__((assert_static(#COND), unused)) \
|
||||
int STATIC_PASTE1(assert_static_, __COUNTER__); \
|
||||
JS_END_MACRO
|
||||
|
||||
#define STATIC_ASSUME(COND) \
|
||||
JS_BEGIN_MACRO \
|
||||
__attribute__((assume_static(#COND), unused)) \
|
||||
int STATIC_PASTE1(assume_static_, __COUNTER__); \
|
||||
JS_END_MACRO
|
||||
|
||||
#define STATIC_ASSERT_RUNTIME(COND) \
|
||||
JS_BEGIN_MACRO \
|
||||
__attribute__((assert_static_runtime(#COND), unused)) \
|
||||
int STATIC_PASTE1(assert_static_runtime_, __COUNTER__); \
|
||||
JS_END_MACRO
|
||||
|
||||
#else /* XGILL_PLUGIN */
|
||||
|
||||
#define STATIC_PRECONDITION(COND) /* nothing */
|
||||
#define STATIC_PRECONDITION_ASSUME(COND) /* nothing */
|
||||
#define STATIC_POSTCONDITION(COND) /* nothing */
|
||||
#define STATIC_POSTCONDITION_ASSUME(COND) /* nothing */
|
||||
#define STATIC_INVARIANT(COND) /* nothing */
|
||||
#define STATIC_INVARIANT_ASSUME(COND) /* nothing */
|
||||
|
||||
#define STATIC_ASSERT(COND) JS_BEGIN_MACRO /* nothing */ JS_END_MACRO
|
||||
#define STATIC_ASSUME(COND) JS_BEGIN_MACRO /* nothing */ JS_END_MACRO
|
||||
#define STATIC_ASSERT_RUNTIME(COND) JS_BEGIN_MACRO /* nothing */ JS_END_MACRO
|
||||
|
||||
#endif /* XGILL_PLUGIN */
|
||||
|
||||
#define STATIC_SKIP_INFERENCE STATIC_INVARIANT(skip_inference())
|
||||
|
||||
#endif /* HAVE_STATIC_ANNOTATIONS */
|
||||
|
||||
#endif /* jsstaticcheck_h___ */
|
||||
|
@ -71,8 +71,6 @@
|
||||
#include "jsscope.h"
|
||||
#include "jsstaticcheck.h"
|
||||
#include "jsstr.h"
|
||||
#include "jsbit.h"
|
||||
#include "jsvector.h"
|
||||
#include "jsversion.h"
|
||||
|
||||
#include "vm/GlobalObject.h"
|
||||
|
@ -44,10 +44,10 @@
|
||||
#include "jsapi.h"
|
||||
#include "jsatom.h"
|
||||
#include "jsprvtd.h"
|
||||
#include "jshashtable.h"
|
||||
#include "jslock.h"
|
||||
#include "jscell.h"
|
||||
|
||||
#include "js/HashTable.h"
|
||||
#include "vm/Unicode.h"
|
||||
|
||||
namespace js {
|
||||
|
@ -40,7 +40,6 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "jsstdint.h"
|
||||
#include "jsbit.h" // low-level (NSPR-based) headers next
|
||||
#include "jsprf.h"
|
||||
#include <math.h> // standard headers next
|
||||
|
||||
@ -75,7 +74,6 @@
|
||||
#include "jsscope.h"
|
||||
#include "jsscript.h"
|
||||
#include "jsstaticcheck.h"
|
||||
#include "jstl.h"
|
||||
#include "jstracer.h"
|
||||
#include "jsxml.h"
|
||||
#include "jstypedarray.h"
|
||||
@ -7939,10 +7937,10 @@ PurgeScriptFragments(TraceMonitor* tm, JSScript* script)
|
||||
|
||||
/* A recorder script is being evaluated and can not be destroyed or GC-ed. */
|
||||
JS_ASSERT_IF(tm->recorder,
|
||||
JS_UPTRDIFF(tm->recorder->getTree()->ip, script->code) >= script->length);
|
||||
UnsignedPtrDiff(tm->recorder->getTree()->ip, script->code) >= script->length);
|
||||
|
||||
for (LoopProfileMap::Enum e(*tm->loopProfiles); !e.empty(); e.popFront()) {
|
||||
if (JS_UPTRDIFF(e.front().key, script->code) < script->length)
|
||||
if (UnsignedPtrDiff(e.front().key, script->code) < script->length)
|
||||
e.removeFront();
|
||||
}
|
||||
|
||||
@ -7954,7 +7952,7 @@ PurgeScriptFragments(TraceMonitor* tm, JSScript* script)
|
||||
for (size_t i = 0; i < FRAGMENT_TABLE_SIZE; ++i) {
|
||||
TreeFragment** fragp = &tm->vmfragments[i];
|
||||
while (TreeFragment* frag = *fragp) {
|
||||
if (JS_UPTRDIFF(frag->ip, script->code) < script->length) {
|
||||
if (UnsignedPtrDiff(frag->ip, script->code) < script->length) {
|
||||
/* This fragment is associated with the script. */
|
||||
debug_only_printf(LC_TMTracer,
|
||||
"Disconnecting TreeFragment %p "
|
||||
@ -7976,7 +7974,7 @@ PurgeScriptFragments(TraceMonitor* tm, JSScript* script)
|
||||
|
||||
RecordAttemptMap &table = *tm->recordAttempts;
|
||||
for (RecordAttemptMap::Enum e(table); !e.empty(); e.popFront()) {
|
||||
if (JS_UPTRDIFF(e.front().key, script->code) < script->length)
|
||||
if (UnsignedPtrDiff(e.front().key, script->code) < script->length)
|
||||
e.removeFront();
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,6 @@
|
||||
#include "jsinterp.h"
|
||||
#include "jslock.h"
|
||||
#include "jsnum.h"
|
||||
#include "jsvector.h"
|
||||
#include "jscompartment.h"
|
||||
#include "Writer.h"
|
||||
|
||||
|
@ -58,8 +58,6 @@
|
||||
#include "jsnum.h"
|
||||
#include "jsobj.h"
|
||||
#include "jsstaticcheck.h"
|
||||
#include "jsbit.h"
|
||||
#include "jsvector.h"
|
||||
#include "jstypedarray.h"
|
||||
#include "jsutil.h"
|
||||
|
||||
|
@ -108,7 +108,6 @@ JS_PUBLIC_API(void) JS_Assert(const char *s, const char *file, JSIntn ln)
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include "jscompat.h"
|
||||
#include "jsbit.h"
|
||||
|
||||
/*
|
||||
* Histogram bins count occurrences of values <= the bin label, as follows:
|
||||
@ -142,7 +141,7 @@ ValToBin(uintN logscale, uint32 val)
|
||||
bin = (logscale == 10)
|
||||
? (uintN) ceil(log10((double) val))
|
||||
: (logscale == 2)
|
||||
? (uintN) JS_CeilingLog2(val)
|
||||
? (uintN) JS_CEILING_LOG2W(val)
|
||||
: val;
|
||||
return JS_MIN(bin, 10);
|
||||
}
|
||||
@ -243,7 +242,7 @@ JS_DumpHistogram(JSBasicStats *bs, FILE *fp)
|
||||
if (max > 1e6 && mean > 1e3)
|
||||
cnt = (uint32) ceil(log10((double) cnt));
|
||||
else if (max > 16 && mean > 8)
|
||||
cnt = JS_CeilingLog2(cnt);
|
||||
cnt = JS_CEILING_LOG2W(cnt);
|
||||
for (uintN i = 0; i < cnt; i++)
|
||||
putc('*', fp);
|
||||
}
|
||||
@ -252,147 +251,3 @@ JS_DumpHistogram(JSBasicStats *bs, FILE *fp)
|
||||
}
|
||||
|
||||
#endif /* JS_BASIC_STATS */
|
||||
|
||||
#if defined(DEBUG_notme) && defined(XP_UNIX)
|
||||
|
||||
#define __USE_GNU 1
|
||||
#include <dlfcn.h>
|
||||
#include <string.h>
|
||||
#include "jshash.h"
|
||||
#include "jsprf.h"
|
||||
|
||||
JSCallsite js_calltree_root = {0, NULL, NULL, 0, NULL, NULL, NULL, NULL};
|
||||
|
||||
static JSCallsite *
|
||||
CallTree(void **bp)
|
||||
{
|
||||
void **bpup, **bpdown, *pc;
|
||||
JSCallsite *parent, *site, **csp;
|
||||
Dl_info info;
|
||||
int ok, offset;
|
||||
const char *symbol;
|
||||
char *method;
|
||||
|
||||
/* Reverse the stack frame list to avoid recursion. */
|
||||
bpup = NULL;
|
||||
for (;;) {
|
||||
bpdown = (void**) bp[0];
|
||||
bp[0] = (void*) bpup;
|
||||
if ((void**) bpdown[0] < bpdown)
|
||||
break;
|
||||
bpup = bp;
|
||||
bp = bpdown;
|
||||
}
|
||||
|
||||
/* Reverse the stack again, finding and building a path in the tree. */
|
||||
parent = &js_calltree_root;
|
||||
do {
|
||||
bpup = (void**) bp[0];
|
||||
bp[0] = (void*) bpdown;
|
||||
pc = bp[1];
|
||||
|
||||
csp = &parent->kids;
|
||||
while ((site = *csp) != NULL) {
|
||||
if (site->pc == (uint32)pc) {
|
||||
/* Put the most recently used site at the front of siblings. */
|
||||
*csp = site->siblings;
|
||||
site->siblings = parent->kids;
|
||||
parent->kids = site;
|
||||
|
||||
/* Site already built -- go up the stack. */
|
||||
goto upward;
|
||||
}
|
||||
csp = &site->siblings;
|
||||
}
|
||||
|
||||
/* Check for recursion: see if pc is on our ancestor line. */
|
||||
for (site = parent; site; site = site->parent) {
|
||||
if (site->pc == (uint32)pc)
|
||||
goto upward;
|
||||
}
|
||||
|
||||
/*
|
||||
* Not in tree at all: let's find our symbolic callsite info.
|
||||
* XXX static syms are masked by nearest lower global
|
||||
*/
|
||||
info.dli_fname = info.dli_sname = NULL;
|
||||
ok = dladdr(pc, &info);
|
||||
if (ok < 0) {
|
||||
fprintf(stderr, "dladdr failed!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* XXXbe sub 0x08040000? or something, see dbaron bug with tenthumbs comment */
|
||||
symbol = info.dli_sname;
|
||||
offset = (char*)pc - (char*)info.dli_fbase;
|
||||
method = symbol
|
||||
? strdup(symbol)
|
||||
: JS_smprintf("%s+%X",
|
||||
info.dli_fname ? info.dli_fname : "main",
|
||||
offset);
|
||||
if (!method)
|
||||
return NULL;
|
||||
|
||||
/* Create a new callsite record. */
|
||||
site = (JSCallsite *) OffTheBooks::malloc(sizeof(JSCallsite));
|
||||
if (!site)
|
||||
return NULL;
|
||||
|
||||
/* Insert the new site into the tree. */
|
||||
site->pc = (uint32)pc;
|
||||
site->name = method;
|
||||
site->library = info.dli_fname;
|
||||
site->offset = offset;
|
||||
site->parent = parent;
|
||||
site->siblings = parent->kids;
|
||||
parent->kids = site;
|
||||
site->kids = NULL;
|
||||
|
||||
upward:
|
||||
parent = site;
|
||||
bpdown = bp;
|
||||
bp = bpup;
|
||||
} while (bp);
|
||||
|
||||
return site;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSCallsite *)
|
||||
JS_Backtrace(int skip)
|
||||
{
|
||||
void **bp, **bpdown;
|
||||
|
||||
/* Stack walking code adapted from Kipp's "leaky". */
|
||||
#if defined(__i386)
|
||||
__asm__( "movl %%ebp, %0" : "=g"(bp));
|
||||
#elif defined(__x86_64__)
|
||||
__asm__( "movq %%rbp, %0" : "=g"(bp));
|
||||
#else
|
||||
/*
|
||||
* It would be nice if this worked uniformly, but at least on i386 and
|
||||
* x86_64, it stopped working with gcc 4.1, because it points to the
|
||||
* end of the saved registers instead of the start.
|
||||
*/
|
||||
bp = (void**) __builtin_frame_address(0);
|
||||
#endif
|
||||
while (--skip >= 0) {
|
||||
bpdown = (void**) *bp++;
|
||||
if (bpdown < bp)
|
||||
break;
|
||||
bp = bpdown;
|
||||
}
|
||||
|
||||
return CallTree(bp);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
JS_DumpBacktrace(JSCallsite *trace)
|
||||
{
|
||||
while (trace) {
|
||||
fprintf(stdout, "%s [%s +0x%X]\n", trace->name, trace->library,
|
||||
trace->offset);
|
||||
trace = trace->parent;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* defined(DEBUG_notme) && defined(XP_UNIX) */
|
||||
|
1016
js/src/jsutil.h
1016
js/src/jsutil.h
File diff suppressed because it is too large
Load Diff
@ -42,7 +42,7 @@
|
||||
/*
|
||||
* Implementation details for js::Value in jsapi.h.
|
||||
*/
|
||||
#include "jsutil.h"
|
||||
#include "js/Utility.h"
|
||||
|
||||
JS_BEGIN_EXTERN_C
|
||||
|
||||
|
@ -40,10 +40,12 @@
|
||||
#ifndef jswatchpoint_h___
|
||||
#define jswatchpoint_h___
|
||||
|
||||
#include "jshashtable.h"
|
||||
#include "jsalloc.h"
|
||||
#include "jsprvtd.h"
|
||||
#include "jsapi.h"
|
||||
|
||||
#include "js/HashTable.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
struct WatchKey {
|
||||
|
@ -43,7 +43,6 @@
|
||||
#include "jsapi.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsgc.h"
|
||||
#include "jshashtable.h"
|
||||
#include "jsobj.h"
|
||||
#include "jsgc.h"
|
||||
#include "jsgcmark.h"
|
||||
|
@ -47,6 +47,8 @@
|
||||
#include "jsobj.h"
|
||||
#include "jsgcmark.h"
|
||||
|
||||
#include "js/HashTable.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
// A subclass template of js::HashMap whose keys and values may be garbage-collected. When
|
||||
|
@ -46,7 +46,6 @@
|
||||
#include <string.h>
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsbit.h"
|
||||
#include "jsprf.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsapi.h"
|
||||
@ -68,7 +67,6 @@
|
||||
#include "jsstr.h"
|
||||
#include "jsxml.h"
|
||||
#include "jsstaticcheck.h"
|
||||
#include "jsvector.h"
|
||||
|
||||
#include "vm/GlobalObject.h"
|
||||
|
||||
|
@ -42,7 +42,6 @@
|
||||
#define jsjaeger_baseassembler_h__
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "jstl.h"
|
||||
#include "assembler/assembler/MacroAssemblerCodeRef.h"
|
||||
#include "assembler/assembler/MacroAssembler.h"
|
||||
#include "assembler/assembler/LinkBuffer.h"
|
||||
|
@ -41,7 +41,6 @@
|
||||
#define jsjaeger_compilerbase_h__
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "jstl.h"
|
||||
#include "assembler/assembler/MacroAssembler.h"
|
||||
#include "assembler/assembler/LinkBuffer.h"
|
||||
#include "assembler/assembler/RepatchBuffer.h"
|
||||
|
@ -42,7 +42,6 @@
|
||||
|
||||
#include "jsanalyze.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jstl.h"
|
||||
#include "MethodJIT.h"
|
||||
#include "CodeGenIncludes.h"
|
||||
#include "BaseCompiler.h"
|
||||
|
@ -40,7 +40,6 @@
|
||||
#if !defined jsjaeger_regstate_h__ && defined JS_METHODJIT
|
||||
#define jsjaeger_regstate_h__
|
||||
|
||||
#include "jsbit.h"
|
||||
#include "assembler/assembler/MacroAssembler.h"
|
||||
|
||||
namespace js {
|
||||
|
@ -41,10 +41,9 @@
|
||||
#define jsjaeger_poly_ic_h__
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "jstl.h"
|
||||
#include "jsvector.h"
|
||||
#include "assembler/assembler/MacroAssembler.h"
|
||||
#include "assembler/assembler/CodeLocation.h"
|
||||
#include "js/Vector.h"
|
||||
#include "methodjit/MethodJIT.h"
|
||||
#include "methodjit/ICRepatcher.h"
|
||||
#include "BaseAssembler.h"
|
||||
|
@ -42,7 +42,6 @@
|
||||
#define jsstub_compiler_h__
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "jstl.h"
|
||||
#include "MethodJIT.h"
|
||||
#include "methodjit/FrameState.h"
|
||||
#include "CodeGenIncludes.h"
|
||||
|
@ -77,7 +77,6 @@
|
||||
#include "jstypedarrayinlines.h"
|
||||
#include "jsxml.h"
|
||||
#include "jsperf.h"
|
||||
#include "jshashtable.h"
|
||||
|
||||
#include "prmjtime.h"
|
||||
|
||||
|
@ -46,11 +46,9 @@
|
||||
#include "jscntxt.h"
|
||||
#include "jscompartment.h"
|
||||
#include "jsfun.h"
|
||||
#include "jshashtable.h"
|
||||
#include "jsobj.h"
|
||||
#include "jsprf.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsvector.h"
|
||||
|
||||
using namespace js;
|
||||
|
||||
|
@ -42,7 +42,9 @@
|
||||
#define jsoptparse_h__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <jsvector.h>
|
||||
|
||||
#include "js/Vector.h"
|
||||
#include "jsalloc.h"
|
||||
|
||||
namespace js {
|
||||
namespace cli {
|
||||
|
@ -47,10 +47,8 @@
|
||||
#include "jsapi.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "jshashtable.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jslock.h"
|
||||
#include "jsvector.h"
|
||||
#include "jsworkers.h"
|
||||
|
||||
extern size_t gMaxStackSize;
|
||||
|
@ -38,7 +38,6 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "jsprf.h"
|
||||
#include "jstl.h"
|
||||
|
||||
#include "jscompartment.h"
|
||||
#include "jsiter.h"
|
||||
|
@ -45,7 +45,6 @@
|
||||
#include "jsemit.h"
|
||||
#include "jsgcmark.h"
|
||||
#include "jsobj.h"
|
||||
#include "jstl.h"
|
||||
#include "jswrapper.h"
|
||||
#include "jsarrayinlines.h"
|
||||
#include "jsinterpinlines.h"
|
||||
|
@ -47,9 +47,10 @@
|
||||
#include "jscntxt.h"
|
||||
#include "jscompartment.h"
|
||||
#include "jsgc.h"
|
||||
#include "jshashtable.h"
|
||||
#include "jsweakmap.h"
|
||||
#include "jswrapper.h"
|
||||
|
||||
#include "js/HashTable.h"
|
||||
#include "vm/GlobalObject.h"
|
||||
|
||||
namespace js {
|
||||
|
@ -43,7 +43,8 @@
|
||||
|
||||
#include "jsfun.h"
|
||||
#include "jsiter.h"
|
||||
#include "jsvector.h"
|
||||
|
||||
#include "js/Vector.h"
|
||||
|
||||
extern JSObject *
|
||||
js_InitObjectClass(JSContext *cx, JSObject *obj);
|
||||
|
@ -43,7 +43,8 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include "jsobj.h"
|
||||
#include "jstl.h"
|
||||
|
||||
#include "js/TemplateLib.h"
|
||||
|
||||
#include "yarr/Yarr.h"
|
||||
#if ENABLE_YARR_JIT
|
||||
|
@ -42,7 +42,8 @@
|
||||
#define RegExpStatics_h__
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "jsvector.h"
|
||||
|
||||
#include "js/Vector.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
|
@ -41,7 +41,6 @@
|
||||
/* Private maps (hashtables). */
|
||||
|
||||
#include "xpcprivate.h"
|
||||
#include "jsbit.h"
|
||||
|
||||
/***************************************************************************/
|
||||
// static shared...
|
||||
|
@ -46,7 +46,6 @@
|
||||
#include "XPCWrapper.h"
|
||||
#include "nsWrapperCacheInlines.h"
|
||||
#include "xpclog.h"
|
||||
#include "jstl.h"
|
||||
#include "nsINode.h"
|
||||
#include "xpcquickstubs.h"
|
||||
#include "jsproxy.h"
|
||||
|
@ -47,7 +47,6 @@
|
||||
|
||||
#include "jsstr.h"
|
||||
#include "jsprvtd.h"
|
||||
#include "jstl.h"
|
||||
#include "vm/String.h"
|
||||
#include "assembler/wtf/Platform.h"
|
||||
#if ENABLE_YARR_JIT
|
||||
|
@ -40,7 +40,7 @@
|
||||
#define nsContentIndexCache_h__
|
||||
|
||||
#include "nscore.h"
|
||||
#include "jshashtable.h"
|
||||
#include "js/HashTable.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user