зеркало из https://github.com/mozilla/gecko-dev.git
157 строки
4.5 KiB
C++
157 строки
4.5 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
* vim: set ts=8 sts=2 et sw=2 tw=80:
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
/* Various JS utility functions. */
|
|
|
|
#include "jsutil.h"
|
|
|
|
#include "mozilla/Assertions.h"
|
|
#include "mozilla/Atomics.h"
|
|
#include "mozilla/Maybe.h"
|
|
#include "mozilla/ThreadLocal.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "jstypes.h"
|
|
|
|
#include "js/Utility.h"
|
|
#include "util/Windows.h"
|
|
#include "vm/HelperThreads.h"
|
|
|
|
using namespace js;
|
|
|
|
using mozilla::Maybe;
|
|
|
|
#if defined(DEBUG) || defined(JS_OOM_BREAKPOINT)
|
|
/* For OOM testing functionality in Utility.h. */
|
|
namespace js {
|
|
|
|
mozilla::Atomic<AutoEnterOOMUnsafeRegion*> AutoEnterOOMUnsafeRegion::owner_;
|
|
|
|
namespace oom {
|
|
|
|
JS_PUBLIC_DATA FailureSimulator simulator;
|
|
static MOZ_THREAD_LOCAL(uint32_t) threadType;
|
|
|
|
bool InitThreadType() { return threadType.init(); }
|
|
|
|
void SetThreadType(ThreadType type) { threadType.set(type); }
|
|
|
|
uint32_t GetThreadType(void) { return threadType.get(); }
|
|
|
|
static inline bool IsHelperThreadType(uint32_t thread) {
|
|
return thread != THREAD_TYPE_NONE && thread != THREAD_TYPE_MAIN;
|
|
}
|
|
|
|
void FailureSimulator::simulateFailureAfter(Kind kind, uint64_t checks,
|
|
uint32_t thread, bool always) {
|
|
Maybe<AutoLockHelperThreadState> lock;
|
|
if (IsHelperThreadType(targetThread_) || IsHelperThreadType(thread)) {
|
|
lock.emplace();
|
|
HelperThreadState().waitForAllThreadsLocked(lock.ref());
|
|
}
|
|
|
|
MOZ_ASSERT(counter_ + checks > counter_);
|
|
MOZ_ASSERT(thread > js::THREAD_TYPE_NONE && thread < js::THREAD_TYPE_MAX);
|
|
targetThread_ = thread;
|
|
maxChecks_ = counter_ + checks;
|
|
failAlways_ = always;
|
|
kind_ = kind;
|
|
}
|
|
|
|
void FailureSimulator::reset() {
|
|
Maybe<AutoLockHelperThreadState> lock;
|
|
if (IsHelperThreadType(targetThread_)) {
|
|
lock.emplace();
|
|
HelperThreadState().waitForAllThreadsLocked(lock.ref());
|
|
}
|
|
|
|
targetThread_ = THREAD_TYPE_NONE;
|
|
maxChecks_ = UINT64_MAX;
|
|
failAlways_ = false;
|
|
kind_ = Kind::Nothing;
|
|
}
|
|
|
|
} // namespace oom
|
|
} // namespace js
|
|
#endif // defined(DEBUG) || defined(JS_OOM_BREAKPOINT)
|
|
|
|
bool js::gDisablePoisoning = false;
|
|
|
|
JS_PUBLIC_DATA arena_id_t js::MallocArena;
|
|
JS_PUBLIC_DATA arena_id_t js::ArrayBufferContentsArena;
|
|
JS_PUBLIC_DATA arena_id_t js::StringBufferArena;
|
|
|
|
void js::InitMallocAllocator() {
|
|
MallocArena = moz_create_arena();
|
|
ArrayBufferContentsArena = moz_create_arena();
|
|
StringBufferArena = moz_create_arena();
|
|
}
|
|
|
|
void js::ShutDownMallocAllocator() {
|
|
// Until Bug 1364359 is fixed it is unsafe to call moz_dispose_arena.
|
|
// moz_dispose_arena(MallocArena);
|
|
// moz_dispose_arena(ArrayBufferContentsArena);
|
|
}
|
|
|
|
#ifdef MOZ_DEBUG
|
|
extern void js::AssertJSStringBufferInCorrectArena(const void* ptr) {
|
|
// `jemalloc_ptr_info()` only exists if MOZ_MEMORY is defined, and it only
|
|
// returns an arenaId if MOZ_DEBUG is defined. Otherwise, this function is
|
|
// a no-op.
|
|
# if defined(MOZ_MEMORY) && defined(MOZ_DEBUG)
|
|
if (ptr) {
|
|
jemalloc_ptr_info_t ptrInfo{};
|
|
jemalloc_ptr_info(ptr, &ptrInfo);
|
|
MOZ_ASSERT(ptrInfo.tag != TagUnknown);
|
|
MOZ_ASSERT(ptrInfo.arenaId == js::StringBufferArena);
|
|
}
|
|
# endif
|
|
}
|
|
#endif
|
|
|
|
JS_PUBLIC_API void JS_Assert(const char* s, const char* file, int ln) {
|
|
MOZ_ReportAssertionFailure(s, file, ln);
|
|
MOZ_CRASH();
|
|
}
|
|
|
|
#ifdef __linux__
|
|
|
|
# include <malloc.h>
|
|
# include <stdlib.h>
|
|
|
|
namespace js {
|
|
|
|
// This function calls all the vanilla heap allocation functions. It is never
|
|
// called, and exists purely to help config/check_vanilla_allocations.py. See
|
|
// that script for more details.
|
|
extern MOZ_COLD void AllTheNonBasicVanillaNewAllocations() {
|
|
// posix_memalign and aligned_alloc aren't available on all Linux
|
|
// configurations.
|
|
// valloc was deprecated in Android 5.0
|
|
// char* q;
|
|
// posix_memalign((void**)&q, 16, 16);
|
|
|
|
intptr_t p = intptr_t(malloc(16)) + intptr_t(calloc(1, 16)) +
|
|
intptr_t(realloc(nullptr, 16)) + intptr_t(new char) +
|
|
intptr_t(new char) + intptr_t(new char) +
|
|
intptr_t(new char[16]) + intptr_t(memalign(16, 16)) +
|
|
// intptr_t(q) +
|
|
// intptr_t(aligned_alloc(16, 16)) +
|
|
// intptr_t(valloc(4096)) +
|
|
intptr_t(strdup("dummy"));
|
|
|
|
printf("%u\n", uint32_t(p)); // make sure |p| is not optimized away
|
|
|
|
free((int*)p); // this would crash if ever actually called
|
|
|
|
MOZ_CRASH();
|
|
}
|
|
|
|
} // namespace js
|
|
|
|
#endif // __linux__
|