Merge tracemonkey to mozilla-central.

This commit is contained in:
Chris Leary 2011-03-31 15:47:46 -07:00
commit 347b8d483b
94 changed files with 1374 additions and 893 deletions

44
config/check_source_count.py Executable file
View File

@ -0,0 +1,44 @@
#!/usr/bin/env python
# Usage: check_source_count.py SEARCH_TERM COUNT ERROR_LOCATION REPLACEMENT [FILES...]
# Checks that FILES contains exactly COUNT matches of SEARCH_TERM. If it does
# not, an error message is printed, quoting ERROR_LOCATION, which should
# probably be the filename and line number of the erroneous call to
# check_source_count.py.
import sys
import os
import re
search_string = sys.argv[1]
expected_count = int(sys.argv[2])
error_location = sys.argv[3]
replacement = sys.argv[4]
files = sys.argv[5:]
details = {}
count = 0
for f in files:
text = file(f).read()
match = re.findall(search_string, text)
if match:
num = len(match)
count += num
details[f] = num
if count == expected_count:
print "TEST-PASS | check_source_count.py %s | %d" % (search_string, expected_count)
else:
print "TEST-UNEXPECTED-FAIL | check_source_count.py %s | " % (search_string),
if count < expected_count:
print "There are less occurences of /%s/ than expected. This may mean that you have removed some, but forgotten to account for it %s." % (search_string, error_location)
else:
print "There are more occurences of /%s/ than expected. We're trying to prevent an increase in the number of %s's, using %s if possible. If it in unavoidable, you should update the expected count %s." % (search_string, search_string, replacement, error_location)
print "Expected: %d; found: %d" % (expected_count, count)
for k in sorted(details):
print "Found %d occurences in %s" % (details[k],k)
sys.exit(-1)

View File

@ -19,7 +19,7 @@
#
# If this script fails:
# - You need to find the uses of vanilla new/delete and replace them with
# js_new()/js_delete().
# {js::OffTheBooks,JSContext,JSRuntime}::{new_,/array_new}.
# - Run this script on each of the .o files, that should narrow it down.
# - After that, one way to find them is to run 'objdump -r -C' on the
# relevant .o files. For example, you might search for 'operator new' and

View File

@ -88,7 +88,7 @@ MODULE_OPTIMIZE_FLAGS = -O2 -ip
endif
else # not INTEL_CXX
FAIL_ON_WARNINGS = 1
#FAIL_ON_WARNINGS = 1
MODULE_OPTIMIZE_FLAGS = -O3 -fstrict-aliasing -fno-stack-protector
# We normally want -fomit-frame-pointer, but we want an explicit
@ -592,11 +592,42 @@ endif
# number to go down over time, by fixing OOMs.
ifdef DEBUG
check-ooms:
$(wildcard $(RUN_TEST_PROGRAM)) $(PYTHON) -u $(srcdir)/config/find_OOM_errors.py --regression 129
$(wildcard $(RUN_TEST_PROGRAM)) $(PYTHON) -u $(srcdir)/config/find_OOM_errors.py --regression 125
check:: check-ooms
endif
## Prevent regressing in our deprecation of non-preferred memory management functions.
# We use all the files in the distribution so that different configurations
# don't give different results. We skip the contents of objdirs using |find|
# (it can't be done with %-expansion, because the files we want to skip aren't
# in the vpath).
ifneq ($(OS_ARCH),WINNT) # FIXME: this should be made work on Windows too.
ALL_FILES=$(shell find $(srcdir) \( -name "*.cpp" -o -name "*.h" \) -not -path "*/dist/*")
check-malloc-function-usage: $(filter-out %jsutil.h %jscntxt.h, $(ALL_FILES))
# js_malloc and friends are only used by other memory managers, and should
# never be used elsewhere directly.
$(srcdir)/config/check_source_count.py "\bjs_malloc\b" 0 \
"in Makefile.in" "cx->malloc_ or rt->malloc_" $^
$(srcdir)/config/check_source_count.py "\bjs_calloc\b" 0 \
"in Makefile.in" "cx->calloc_ or rt->calloc_" $^
$(srcdir)/config/check_source_count.py "\bjs_realloc\b" 0 \
"in Makefile.in" "cx->realloc_ or rt->realloc_" $^
$(srcdir)/config/check_source_count.py "\bjs_free\b" 0 \
"in Makefile.in" "cx->free_" $^
# We desire these numbers to go down, not up. See "User guide to memory
# management within SpiderMonkey" in jsutil.h.
$(srcdir)/config/check_source_count.py OffTheBooks:: 54 \
"in Makefile.in" "{cx,rt}->{new_,new_array,malloc_,calloc_,realloc_}" $^
# This should go to zero, if possible.
$(srcdir)/config/check_source_count.py UnwantedForeground:: 36 \
"in Makefile.in" "{cx,rt}->{free_,delete_,array_delete}" $^
check:: check-malloc-function-usage
endif
ifndef WINCE
JITFLAGS = ,m,j,mj,mjp,am,amj,amjp,amd
check::

View File

@ -70,6 +70,8 @@ namespace JSC {
// These are reference-counted. A new one starts with a count of 1.
class ExecutablePool {
JS_DECLARE_ALLOCATION_FRIENDS_FOR_PRIVATE_CONSTRUCTOR;
friend class ExecutableAllocator;
private:
struct Allocation {
@ -100,9 +102,7 @@ public:
JS_ASSERT(m_refCount != 0);
JS_ASSERT_IF(willDestroy, m_refCount = 1);
if (--m_refCount == 0) {
/* We can't (easily) use js_delete() here because the destructor is private. */
this->~ExecutablePool();
js_free(this);
js::UnwantedForeground::delete_(this);
}
}
@ -236,9 +236,7 @@ private:
if (!a.pages)
return NULL;
/* We can't (easily) use js_new() here because the constructor is private. */
void *memory = js_malloc(sizeof(ExecutablePool));
return memory ? new(memory) ExecutablePool(a) : NULL;
return js::OffTheBooks::new_<ExecutablePool>(a);
}
ExecutablePool* poolForSize(size_t n)

View File

@ -74,15 +74,15 @@ static void printCallSite(const char* file, int line, const char* function)
void WTFReportAssertionFailure(const char* file, int line, const char* function, const char* assertion)
{
if (assertion)
printf_stderr_common("ASSERTION FAILED: %s\n", assertion);
printf_stderr_common("Assertion failure: %s\n", assertion);
else
printf_stderr_common("SHOULD NEVER BE REACHED\n");
printf_stderr_common("Should never be reached\n");
printCallSite(file, line, function);
}
void WTFReportAssertionFailureWithMessage(const char* file, int line, const char* function, const char* assertion, const char* format, ...)
{
printf_stderr_common("ASSERTION FAILED: ");
printf_stderr_common("Assertion failure: ");
va_list args;
va_start(args, format);
vprintf_stderr_common(format, args);
@ -93,13 +93,13 @@ void WTFReportAssertionFailureWithMessage(const char* file, int line, const char
void WTFReportArgumentAssertionFailure(const char* file, int line, const char* function, const char* argName, const char* assertion)
{
printf_stderr_common("ARGUMENT BAD: %s, %s\n", argName, assertion);
printf_stderr_common("Argument bad: %s, %s\n", argName, assertion);
printCallSite(file, line, function);
}
void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...)
{
printf_stderr_common("FATAL ERROR: ");
printf_stderr_common("Fatal error: ");
va_list args;
va_start(args, format);
vprintf_stderr_common(format, args);
@ -110,7 +110,7 @@ void WTFReportFatalError(const char* file, int line, const char* function, const
void WTFReportError(const char* file, int line, const char* function, const char* format, ...)
{
printf_stderr_common("ERROR: ");
printf_stderr_common("Error: ");
va_list args;
va_start(args, format);
vprintf_stderr_common(format, args);

View File

@ -0,0 +1,44 @@
#!/usr/bin/env python
# Usage: check_source_count.py SEARCH_TERM COUNT ERROR_LOCATION REPLACEMENT [FILES...]
# Checks that FILES contains exactly COUNT matches of SEARCH_TERM. If it does
# not, an error message is printed, quoting ERROR_LOCATION, which should
# probably be the filename and line number of the erroneous call to
# check_source_count.py.
import sys
import os
import re
search_string = sys.argv[1]
expected_count = int(sys.argv[2])
error_location = sys.argv[3]
replacement = sys.argv[4]
files = sys.argv[5:]
details = {}
count = 0
for f in files:
text = file(f).read()
match = re.findall(search_string, text)
if match:
num = len(match)
count += num
details[f] = num
if count == expected_count:
print "TEST-PASS | check_source_count.py %s | %d" % (search_string, expected_count)
else:
print "TEST-UNEXPECTED-FAIL | check_source_count.py %s | " % (search_string),
if count < expected_count:
print "There are less occurences of /%s/ than expected. This may mean that you have removed some, but forgotten to account for it %s." % (search_string, error_location)
else:
print "There are more occurences of /%s/ than expected. We're trying to prevent an increase in the number of %s's, using %s if possible. If it in unavoidable, you should update the expected count %s." % (search_string, search_string, replacement, error_location)
print "Expected: %d; found: %d" % (expected_count, count)
for k in sorted(details):
print "Found %d occurences in %s" % (details[k],k)
sys.exit(-1)

View File

@ -19,7 +19,7 @@
#
# If this script fails:
# - You need to find the uses of vanilla new/delete and replace them with
# js_new()/js_delete().
# {js::OffTheBooks,JSContext,JSRuntime}::{new_,/array_new}.
# - Run this script on each of the .o files, that should narrow it down.
# - After that, one way to find them is to run 'objdump -r -C' on the
# relevant .o files. For example, you might search for 'operator new' and

View File

@ -1844,7 +1844,7 @@ ImplicitConvert(JSContext* cx,
return false;
char** charBuffer = static_cast<char**>(buffer);
*charBuffer = js_array_new<char>(nbytes + 1);
*charBuffer = cx->array_new<char>(nbytes + 1);
if (!*charBuffer) {
JS_ReportAllocationOverflow(cx);
return false;
@ -1861,7 +1861,7 @@ ImplicitConvert(JSContext* cx,
// JSString's buffer, but this approach is safer if the caller happens
// to modify the string.)
jschar** jscharBuffer = static_cast<jschar**>(buffer);
*jscharBuffer = js_array_new<jschar>(sourceLength + 1);
*jscharBuffer = cx->array_new<jschar>(sourceLength + 1);
if (!*jscharBuffer) {
JS_ReportAllocationOverflow(cx);
return false;
@ -1946,7 +1946,7 @@ ImplicitConvert(JSContext* cx,
// Convert into an intermediate, in case of failure.
size_t elementSize = CType::GetSize(cx, baseType);
size_t arraySize = elementSize * targetLength;
AutoPtr<char>::Array intermediate(js_array_new<char>(arraySize));
AutoPtr<char>::Array intermediate(cx->array_new<char>(arraySize));
if (!intermediate) {
JS_ReportAllocationOverflow(cx);
return false;
@ -1983,7 +1983,7 @@ ImplicitConvert(JSContext* cx,
// Convert into an intermediate, in case of failure.
size_t structSize = CType::GetSize(cx, targetType);
AutoPtr<char>::Array intermediate(js_array_new<char>(structSize));
AutoPtr<char>::Array intermediate(cx->array_new<char>(structSize));
if (!intermediate) {
JS_ReportAllocationOverflow(cx);
return false;
@ -2702,7 +2702,7 @@ CType::Finalize(JSContext* cx, JSObject* obj)
// Free the FunctionInfo.
ASSERT_OK(JS_GetReservedSlot(cx, obj, SLOT_FNINFO, &slot));
if (!JSVAL_IS_VOID(slot))
js_delete(static_cast<FunctionInfo*>(JSVAL_TO_PRIVATE(slot)));
cx->delete_(static_cast<FunctionInfo*>(JSVAL_TO_PRIVATE(slot)));
break;
}
@ -2711,7 +2711,7 @@ CType::Finalize(JSContext* cx, JSObject* obj)
ASSERT_OK(JS_GetReservedSlot(cx, obj, SLOT_FIELDINFO, &slot));
if (!JSVAL_IS_VOID(slot)) {
void* info = JSVAL_TO_PRIVATE(slot);
js_delete(static_cast<FieldInfoHash*>(info));
cx->delete_(static_cast<FieldInfoHash*>(info));
}
}
@ -2721,8 +2721,8 @@ CType::Finalize(JSContext* cx, JSObject* obj)
ASSERT_OK(JS_GetReservedSlot(cx, obj, SLOT_FFITYPE, &slot));
if (!JSVAL_IS_VOID(slot)) {
ffi_type* ffiType = static_cast<ffi_type*>(JSVAL_TO_PRIVATE(slot));
js_array_delete(ffiType->elements);
js_delete(ffiType);
cx->array_delete(ffiType->elements);
cx->delete_(ffiType);
}
break;
@ -3701,7 +3701,7 @@ ArrayType::BuildFFIType(JSContext* cx, JSObject* obj)
// values. It would be nice to not do all the work of setting up 'elements',
// but some libffi platforms currently require that it be meaningful. I'm
// looking at you, x86_64.
AutoPtr<ffi_type> ffiType(js_new<ffi_type>());
AutoPtr<ffi_type> ffiType(cx->new_<ffi_type>());
if (!ffiType) {
JS_ReportOutOfMemory(cx);
return NULL;
@ -3710,7 +3710,7 @@ ArrayType::BuildFFIType(JSContext* cx, JSObject* obj)
ffiType->type = FFI_TYPE_STRUCT;
ffiType->size = CType::GetSize(cx, obj);
ffiType->alignment = CType::GetAlignment(cx, obj);
ffiType->elements = js_array_new<ffi_type*>(length + 1);
ffiType->elements = cx->array_new<ffi_type*>(length + 1);
if (!ffiType->elements) {
JS_ReportAllocationOverflow(cx);
return NULL;
@ -4033,7 +4033,7 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj, JSObject* fieldsObj
// its constituents. (We cannot simply stash the hash in a reserved slot now
// to get GC safety for free, since if anything in this function fails we
// do not want to mutate 'typeObj'.)
AutoPtr<FieldInfoHash> fields(js_new<FieldInfoHash>());
AutoPtr<FieldInfoHash> fields(cx->new_<FieldInfoHash>());
Array<jsval, 16> fieldRootsArray;
if (!fields || !fields->init(len) || !fieldRootsArray.appendN(JSVAL_VOID, len)) {
JS_ReportOutOfMemory(cx);
@ -4142,7 +4142,7 @@ StructType::BuildFFIType(JSContext* cx, JSObject* obj)
size_t structSize = CType::GetSize(cx, obj);
size_t structAlign = CType::GetAlignment(cx, obj);
AutoPtr<ffi_type> ffiType(js_new<ffi_type>());
AutoPtr<ffi_type> ffiType(cx->new_<ffi_type>());
if (!ffiType) {
JS_ReportOutOfMemory(cx);
return NULL;
@ -4151,7 +4151,7 @@ StructType::BuildFFIType(JSContext* cx, JSObject* obj)
AutoPtr<ffi_type*>::Array elements;
if (len != 0) {
elements = js_array_new<ffi_type*>(len + 1);
elements = cx->array_new<ffi_type*>(len + 1);
if (!elements) {
JS_ReportOutOfMemory(cx);
return NULL;
@ -4170,7 +4170,7 @@ StructType::BuildFFIType(JSContext* cx, JSObject* obj)
// Represent an empty struct as having a size of 1 byte, just like C++.
JS_ASSERT(structSize == 1);
JS_ASSERT(structAlign == 1);
elements = js_array_new<ffi_type*>(2);
elements = cx->array_new<ffi_type*>(2);
if (!elements) {
JS_ReportOutOfMemory(cx);
return NULL;
@ -4511,14 +4511,14 @@ struct AutoValue
~AutoValue()
{
js_array_delete(static_cast<char*>(mData));
UnwantedForeground::array_delete(static_cast<char*>(mData));
}
bool SizeToType(JSContext* cx, JSObject* type)
{
// Allocate a minimum of sizeof(ffi_arg) to handle small integers.
size_t size = Align(CType::GetSize(cx, type), sizeof(ffi_arg));
mData = js_array_new<char>(size);
mData = cx->array_new<char>(size);
if (mData)
memset(mData, 0, size);
return mData != NULL;
@ -4723,7 +4723,7 @@ NewFunctionInfo(JSContext* cx,
jsval* argTypes,
uintN argLength)
{
AutoPtr<FunctionInfo> fninfo(js_new<FunctionInfo>());
AutoPtr<FunctionInfo> fninfo(cx->new_<FunctionInfo>());
if (!fninfo) {
JS_ReportOutOfMemory(cx);
return NULL;
@ -5199,7 +5199,7 @@ CClosure::Create(JSContext* cx,
JS_ASSERT(!fninfo->mIsVariadic);
JS_ASSERT(GetABICode(cx, fninfo->mABI) != ABI_WINAPI);
AutoPtr<ClosureInfo> cinfo(js_new<ClosureInfo>());
AutoPtr<ClosureInfo> cinfo(cx->new_<ClosureInfo>());
if (!cinfo) {
JS_ReportOutOfMemory(cx);
return NULL;
@ -5312,7 +5312,7 @@ CClosure::Finalize(JSContext* cx, JSObject* obj)
if (cinfo->closure)
ffi_closure_free(cinfo->closure);
js_delete(cinfo);
cx->delete_(cinfo);
}
void
@ -5489,7 +5489,7 @@ CData::Create(JSContext* cx,
// attach the buffer. since it might not be 2-byte aligned, we need to
// allocate an aligned space for it and store it there. :(
char** buffer = js_new<char*>();
char** buffer = cx->new_<char*>();
if (!buffer) {
JS_ReportOutOfMemory(cx);
return NULL;
@ -5501,11 +5501,11 @@ CData::Create(JSContext* cx,
} else {
// Initialize our own buffer.
size_t size = CType::GetSize(cx, typeObj);
data = js_array_new<char>(size);
data = cx->array_new<char>(size);
if (!data) {
// Report a catchable allocation error.
JS_ReportAllocationOverflow(cx);
js_delete(buffer);
Foreground::delete_(buffer);
return NULL;
}
@ -5518,8 +5518,8 @@ CData::Create(JSContext* cx,
*buffer = data;
if (!JS_SetReservedSlot(cx, dataObj, SLOT_DATA, PRIVATE_TO_JSVAL(buffer))) {
if (ownResult)
js_array_delete(data);
js_delete(buffer);
Foreground::array_delete(data);
Foreground::delete_(buffer);
return NULL;
}
@ -5541,8 +5541,8 @@ CData::Finalize(JSContext* cx, JSObject* obj)
char** buffer = static_cast<char**>(JSVAL_TO_PRIVATE(slot));
if (owns)
js_array_delete(*buffer);
js_delete(buffer);
cx->array_delete(*buffer);
cx->delete_(buffer);
}
JSObject*
@ -5826,14 +5826,14 @@ Int64Base::Construct(JSContext* cx,
js::AutoObjectRooter root(cx, result);
// attach the Int64's data
JSUint64* buffer = js_new<JSUint64>(data);
JSUint64* buffer = cx->new_<JSUint64>(data);
if (!buffer) {
JS_ReportOutOfMemory(cx);
return NULL;
}
if (!JS_SetReservedSlot(cx, result, SLOT_INT64, PRIVATE_TO_JSVAL(buffer))) {
js_delete(buffer);
Foreground::delete_(buffer);
return NULL;
}
@ -5850,7 +5850,7 @@ Int64Base::Finalize(JSContext* cx, JSObject* obj)
if (!JS_GetReservedSlot(cx, obj, SLOT_INT64, &slot) || JSVAL_IS_VOID(slot))
return;
js_delete(static_cast<JSUint64*>(JSVAL_TO_PRIVATE(slot)));
cx->delete_(static_cast<JSUint64*>(JSVAL_TO_PRIVATE(slot)));
}
JSUint64

View File

@ -56,18 +56,18 @@ template<class T>
class OperatorDelete
{
public:
static void destroy(T* ptr) { js_delete(ptr); }
static void destroy(T* ptr) { UnwantedForeground::delete_(ptr); }
};
template<class T>
class OperatorArrayDelete
{
public:
static void destroy(T* ptr) { js_array_delete(ptr); }
static void destroy(T* ptr) { UnwantedForeground::array_delete(ptr); }
};
// Class that takes ownership of a pointer T*, and calls js_delete() or
// js_array_delete() upon destruction.
// Class that takes ownership of a pointer T*, and calls cx->delete_() or
// cx->array_delete() upon destruction.
template<class T, class DeleteTraits = OperatorDelete<T> >
class AutoPtr {
private:

View File

@ -0,0 +1,8 @@
var obj = new Object();
var passed = true;
for (var i = 0; i < 100; i++) {
if (obj['-1'] == null)
obj['-1'] = new Array();
assertEq(obj['-1'] == null, false);
obj = new Object();
}

Binary file not shown.

View File

@ -64,6 +64,7 @@ CPPSRCS = \
testGetPropertyDefault.cpp \
testIntString.cpp \
testLookup.cpp \
testLooselyEqual.cpp \
testNewObject.cpp \
testOps.cpp \
testPropCache.cpp \

View File

@ -0,0 +1,168 @@
#include "tests.h"
#include <limits>
#include <math.h>
using namespace std;
struct LooseEqualityFixture : public JSAPITest
{
jsval qNaN;
jsval sNaN;
jsval d42;
jsval i42;
jsval undef;
jsval null;
jsval obj;
jsval poszero;
jsval negzero;
virtual ~LooseEqualityFixture() {}
virtual bool init() {
if (!JSAPITest::init())
return false;
qNaN = DOUBLE_TO_JSVAL(numeric_limits<double>::quiet_NaN());
sNaN = DOUBLE_TO_JSVAL(numeric_limits<double>::signaling_NaN());
d42 = DOUBLE_TO_JSVAL(42.0);
i42 = INT_TO_JSVAL(42);
undef = JSVAL_VOID;
null = JSVAL_NULL;
obj = OBJECT_TO_JSVAL(global);
poszero = DOUBLE_TO_JSVAL(0.0);
negzero = DOUBLE_TO_JSVAL(-0.0);
#ifdef XP_WIN
# define copysign _copysign
#endif
JS_ASSERT(copysign(1.0, JSVAL_TO_DOUBLE(poszero)) == 1.0);
JS_ASSERT(copysign(1.0, JSVAL_TO_DOUBLE(negzero)) == -1.0);
#ifdef XP_WIN
# undef copysign
#endif
return true;
}
bool leq(jsval x, jsval y) {
JSBool equal;
CHECK(JS_LooselyEqual(cx, x, y, &equal) && equal);
CHECK(JS_LooselyEqual(cx, y, x, &equal) && equal);
return true;
}
bool nleq(jsval x, jsval y) {
JSBool equal;
CHECK(JS_LooselyEqual(cx, x, y, &equal) && !equal);
CHECK(JS_LooselyEqual(cx, y, x, &equal) && !equal);
return true;
}
};
// 11.9.3 1a
BEGIN_FIXTURE_TEST(LooseEqualityFixture, test_undef_leq_undef)
{
CHECK(leq(JSVAL_VOID, JSVAL_VOID));
return true;
}
END_FIXTURE_TEST(LooseEqualityFixture, test_undef_leq_undef)
// 11.9.3 1b
BEGIN_FIXTURE_TEST(LooseEqualityFixture, test_null_leq_null)
{
CHECK(leq(JSVAL_NULL, JSVAL_NULL));
return true;
}
END_FIXTURE_TEST(LooseEqualityFixture, test_null_leq_null)
// 11.9.3 1ci
BEGIN_FIXTURE_TEST(LooseEqualityFixture, test_nan_nleq_all)
{
CHECK(nleq(qNaN, qNaN));
CHECK(nleq(qNaN, sNaN));
CHECK(nleq(sNaN, sNaN));
CHECK(nleq(sNaN, qNaN));
CHECK(nleq(qNaN, d42));
CHECK(nleq(qNaN, i42));
CHECK(nleq(qNaN, undef));
CHECK(nleq(qNaN, null));
CHECK(nleq(qNaN, obj));
CHECK(nleq(sNaN, d42));
CHECK(nleq(sNaN, i42));
CHECK(nleq(sNaN, undef));
CHECK(nleq(sNaN, null));
CHECK(nleq(sNaN, obj));
return true;
}
END_FIXTURE_TEST(LooseEqualityFixture, test_nan_nleq_all)
// 11.9.3 1cii
BEGIN_FIXTURE_TEST(LooseEqualityFixture, test_all_nleq_nan)
{
CHECK(nleq(qNaN, qNaN));
CHECK(nleq(qNaN, sNaN));
CHECK(nleq(sNaN, sNaN));
CHECK(nleq(sNaN, qNaN));
CHECK(nleq(d42, qNaN));
CHECK(nleq(i42, qNaN));
CHECK(nleq(undef, qNaN));
CHECK(nleq(null, qNaN));
CHECK(nleq(obj, qNaN));
CHECK(nleq(d42, sNaN));
CHECK(nleq(i42, sNaN));
CHECK(nleq(undef, sNaN));
CHECK(nleq(null, sNaN));
CHECK(nleq(obj, sNaN));
return true;
}
END_FIXTURE_TEST(LooseEqualityFixture, test_all_nleq_nan)
// 11.9.3 1ciii
BEGIN_FIXTURE_TEST(LooseEqualityFixture, test_leq_same_nums)
{
CHECK(leq(d42, d42));
CHECK(leq(i42, i42));
CHECK(leq(d42, i42));
CHECK(leq(i42, d42));
return true;
}
END_FIXTURE_TEST(LooseEqualityFixture, test_leq_same_nums)
// 11.9.3 1civ
BEGIN_FIXTURE_TEST(LooseEqualityFixture, test_pz_leq_nz)
{
CHECK(leq(poszero, negzero));
return true;
}
END_FIXTURE_TEST(LooseEqualityFixture, test_pz_leq_nz)
// 11.9.3 1cv
BEGIN_FIXTURE_TEST(LooseEqualityFixture, test_nz_leq_pz)
{
CHECK(leq(negzero, poszero));
return true;
}
END_FIXTURE_TEST(LooseEqualityFixture, test_nz_leq_pz)
// 1cvi onwards NOT TESTED
// 11.9.3 2
BEGIN_FIXTURE_TEST(LooseEqualityFixture, test_null_leq_undef)
{
CHECK(leq(null, undef));
return true;
}
END_FIXTURE_TEST(LooseEqualityFixture, test_null_leq_undef)
// 11.9.3 3
BEGIN_FIXTURE_TEST(LooseEqualityFixture, test_undef_leq_null)
{
CHECK(leq(undef, null));
return true;
}
END_FIXTURE_TEST(LooseEqualityFixture, test_undef_leq_null)
// 4 onwards NOT TESTED

View File

@ -27,7 +27,8 @@ struct VersionFixture : public JSAPITest
JSVersion captured;
virtual bool init() {
JSAPITest::init();
if (!JSAPITest::init())
return false;
callbackData = this;
captured = JSVERSION_UNKNOWN;
return JS_DefineFunction(cx, global, "checkVersionHasXML", CheckVersionHasXML, 0, 0) &&

View File

@ -384,7 +384,7 @@ JS_AddArgumentFormatter(JSContext *cx, const char *format, JSArgumentFormatter f
goto out;
mpp = &map->next;
}
map = (JSArgumentFormatMap *) cx->malloc(sizeof *map);
map = (JSArgumentFormatMap *) cx->malloc_(sizeof *map);
if (!map)
return JS_FALSE;
map->format = format;
@ -407,7 +407,7 @@ JS_RemoveArgumentFormatter(JSContext *cx, const char *format)
while ((map = *mpp) != NULL) {
if (map->length == length && !strcmp(map->format, format)) {
*mpp = map->next;
cx->free(map);
cx->free_(map);
return;
}
mpp = &map->next;
@ -520,6 +520,18 @@ JS_DoubleIsInt32(jsdouble d, jsint *ip)
return JSDOUBLE_IS_INT32(d, (int32_t *)ip);
}
JS_PUBLIC_API(int32)
JS_DoubleToInt32(jsdouble d)
{
return js_DoubleToECMAInt32(d);
}
JS_PUBLIC_API(uint32)
JS_DoubleToUint32(jsdouble d)
{
return js_DoubleToECMAUint32(d);
}
JS_PUBLIC_API(JSBool)
JS_ValueToECMAInt32(JSContext *cx, jsval v, int32 *ip)
{
@ -592,6 +604,13 @@ JS_StrictlyEqual(JSContext *cx, jsval v1, jsval v2, JSBool *equal)
return StrictlyEqual(cx, Valueify(v1), Valueify(v2), equal);
}
JS_PUBLIC_API(JSBool)
JS_LooselyEqual(JSContext *cx, jsval v1, jsval v2, JSBool *equal)
{
assertSameCompartment(cx, v1, v2);
return LooselyEqual(cx, Valueify(v1), Valueify(v2), equal);
}
JS_PUBLIC_API(JSBool)
JS_SameValue(JSContext *cx, jsval v1, jsval v2, JSBool *same)
{
@ -650,13 +669,19 @@ JSRuntime::init(uint32 maxbytes)
propTreeDumpFilename = getenv("JS_PROPTREE_DUMPFILE");
#endif
if (!(atomsCompartment = js_new<JSCompartment>(this)) ||
if (!js_InitGC(this, maxbytes))
return false;
if (!(atomsCompartment = this->new_<JSCompartment>(this)) ||
!atomsCompartment->init() ||
!compartments.append(atomsCompartment)) {
Foreground::delete_(atomsCompartment);
return false;
}
if (!js_InitGC(this, maxbytes) || !js_InitAtomState(this))
atomsCompartment->setGCLastBytes(8192);
if (!js_InitAtomState(this))
return false;
wrapObjectCallback = js::TransparentObjectWrapper;
@ -755,7 +780,7 @@ JS_NewRuntime(uint32 maxbytes)
}
#endif /* DEBUG */
void *mem = js_calloc(sizeof(JSRuntime));
void *mem = OffTheBooks::calloc_(sizeof(JSRuntime));
if (!mem)
return NULL;
@ -771,9 +796,7 @@ JS_NewRuntime(uint32 maxbytes)
JS_PUBLIC_API(void)
JS_DestroyRuntime(JSRuntime *rt)
{
rt->~JSRuntime();
js_free(rt);
Foreground::delete_(rt);
}
#ifdef JS_REPRMETER
@ -1179,11 +1202,11 @@ JS_EnterCrossCompartmentCall(JSContext *cx, JSObject *target)
CHECK_REQUEST(cx);
JS_ASSERT(target);
AutoCompartment *call = js_new<AutoCompartment>(cx, target);
AutoCompartment *call = cx->new_<AutoCompartment>(cx, target);
if (!call)
return NULL;
if (!call->enter()) {
js_delete(call);
Foreground::delete_(call);
return NULL;
}
return reinterpret_cast<JSCrossCompartmentCall *>(call);
@ -1221,7 +1244,7 @@ JS_LeaveCrossCompartmentCall(JSCrossCompartmentCall *call)
AutoCompartment *realcall = reinterpret_cast<AutoCompartment *>(call);
CHECK_REQUEST(realcall->context);
realcall->leave();
js_delete(realcall);
Foreground::delete_(realcall);
}
bool
@ -1879,7 +1902,7 @@ NewIdArray(JSContext *cx, jsint length)
JSIdArray *ida;
ida = (JSIdArray *)
cx->calloc(offsetof(JSIdArray, vector) + length * sizeof(jsval));
cx->calloc_(offsetof(JSIdArray, vector) + length * sizeof(jsval));
if (ida)
ida->length = length;
return ida;
@ -2040,19 +2063,19 @@ JS_ComputeThis(JSContext *cx, jsval *vp)
JS_PUBLIC_API(void *)
JS_malloc(JSContext *cx, size_t nbytes)
{
return cx->malloc(nbytes);
return cx->malloc_(nbytes);
}
JS_PUBLIC_API(void *)
JS_realloc(JSContext *cx, void *p, size_t nbytes)
{
return cx->realloc(p, nbytes);
return cx->realloc_(p, nbytes);
}
JS_PUBLIC_API(void)
JS_free(JSContext *cx, void *p)
{
return cx->free(p);
return cx->free_(p);
}
JS_PUBLIC_API(void)
@ -2068,7 +2091,7 @@ JS_strdup(JSContext *cx, const char *s)
void *p;
n = strlen(s) + 1;
p = cx->malloc(n);
p = cx->malloc_(n);
if (!p)
return NULL;
return (char *)memcpy(p, s, n);
@ -2453,7 +2476,7 @@ DumpNotify(JSTracer *trc, void *thing, uint32 kind)
}
edgeNameSize = strlen(edgeName) + 1;
node = (JSHeapDumpNode *) js_malloc(offsetof(JSHeapDumpNode, edgeName) + edgeNameSize);
node = (JSHeapDumpNode *) cx->malloc_(offsetof(JSHeapDumpNode, edgeName) + edgeNameSize);
if (!node) {
dtrc->ok = JS_FALSE;
return;
@ -2605,7 +2628,7 @@ JS_DumpHeap(JSContext *cx, FILE *fp, void* startThing, uint32 startKind,
for (;;) {
next = node->next;
parent = node->parent;
js_free(node);
cx->free_(node);
node = next;
if (node)
break;
@ -2823,7 +2846,7 @@ JS_SetScriptStackQuota(JSContext *cx, size_t quota)
JS_PUBLIC_API(void)
JS_DestroyIdArray(JSContext *cx, JSIdArray *ida)
{
cx->free(ida);
cx->free_(ida);
}
JS_PUBLIC_API(JSBool)
@ -4567,7 +4590,7 @@ JS_CompileScriptForPrincipals(JSContext *cx, JSObject *obj,
return NULL;
JSObject *scriptObj =
JS_CompileUCScriptForPrincipals(cx, obj, principals, chars, length, filename, lineno);
cx->free(chars);
cx->free_(chars);
return scriptObj;
}
@ -4615,7 +4638,7 @@ JS_BufferIsCompilableUnit(JSContext *cx, JSObject *obj, const char *bytes, size_
JS_SetErrorReporter(cx, older);
}
}
cx->free(chars);
cx->free_(chars);
JS_RestoreExceptionState(cx, exnState);
return result;
}
@ -4651,9 +4674,9 @@ CompileFileHelper(JSContext *cx, JSObject *obj, JSPrincipals *principals,
bool hitEOF = false;
while (!hitEOF) {
len *= 2;
jschar* tmpbuf = (jschar *) js_realloc(buf, len * sizeof(jschar));
jschar* tmpbuf = (jschar *) cx->realloc_(buf, len * sizeof(jschar));
if (!tmpbuf) {
cx->free(buf);
cx->free_(buf);
return NULL;
}
buf = tmpbuf;
@ -4668,7 +4691,7 @@ CompileFileHelper(JSContext *cx, JSObject *obj, JSPrincipals *principals,
}
}
} else {
buf = (jschar *) js_malloc(len * sizeof(jschar));
buf = (jschar *) cx->malloc_(len * sizeof(jschar));
if (!buf)
return NULL;
@ -4682,7 +4705,7 @@ CompileFileHelper(JSContext *cx, JSObject *obj, JSPrincipals *principals,
uint32 tcflags = JS_OPTIONS_TO_TCFLAGS(cx) | TCF_NEED_MUTABLE_SCRIPT;
script = Compiler::compileScript(cx, obj, NULL, principals, tcflags, buf, len, filename, 1,
cx->findVersion());
js_free(buf);
cx->free_(buf);
if (!script)
return NULL;
@ -4891,7 +4914,7 @@ JS_CompileFunctionForPrincipals(JSContext *cx, JSObject *obj,
JSFunction *fun = JS_CompileUCFunctionForPrincipals(cx, obj, principals, name,
nargs, argnames, chars, length,
filename, lineno);
cx->free(chars);
cx->free_(chars);
return fun;
}
@ -5054,7 +5077,7 @@ JS_EvaluateScriptForPrincipals(JSContext *cx, JSObject *obj, JSPrincipals *princ
return JS_FALSE;
JSBool ok = JS_EvaluateUCScriptForPrincipals(cx, obj, principals, chars, length,
filename, lineno, rval);
cx->free(chars);
cx->free_(chars);
return ok;
}
@ -5279,7 +5302,7 @@ JS_NewStringCopyZ(JSContext *cx, const char *s)
return NULL;
str = js_NewString(cx, js, n);
if (!str)
cx->free(js);
cx->free_(js);
return str;
}
@ -5829,7 +5852,7 @@ JS_NewRegExpObject(JSContext *cx, JSObject *obj, char *bytes, size_t length, uin
return NULL;
RegExpStatics *res = RegExpStatics::extractFrom(obj);
JSObject *reobj = RegExp::createObject(cx, res, chars, length, flags);
cx->free(chars);
cx->free_(chars);
return reobj;
}
@ -5884,7 +5907,7 @@ JS_NewRegExpObjectNoStatics(JSContext *cx, char *bytes, size_t length, uintN fla
if (!chars)
return NULL;
JSObject *obj = RegExp::createObjectNoStatics(cx, chars, length, flags);
cx->free(chars);
cx->free_(chars);
return obj;
}
@ -5991,7 +6014,7 @@ JS_SaveExceptionState(JSContext *cx)
JSExceptionState *state;
CHECK_REQUEST(cx);
state = (JSExceptionState *) cx->malloc(sizeof(JSExceptionState));
state = (JSExceptionState *) cx->malloc_(sizeof(JSExceptionState));
if (state) {
state->throwing = JS_GetPendingException(cx, &state->exception);
if (state->throwing && JSVAL_IS_GCTHING(state->exception))
@ -6022,7 +6045,7 @@ JS_DropExceptionState(JSContext *cx, JSExceptionState *state)
assertSameCompartment(cx, state->exception);
JS_RemoveValueRoot(cx, &state->exception);
}
cx->free(state);
cx->free_(state);
}
}

View File

@ -664,6 +664,12 @@ JS_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp);
extern JS_PUBLIC_API(JSBool)
JS_DoubleIsInt32(jsdouble d, jsint *ip);
extern JS_PUBLIC_API(int32)
JS_DoubleToInt32(jsdouble d);
extern JS_PUBLIC_API(uint32)
JS_DoubleToUint32(jsdouble d);
/*
* Convert a value to a number, then to an int32, according to the ECMA rules
* for ToInt32.
@ -704,6 +710,9 @@ JS_GetTypeName(JSContext *cx, JSType type);
extern JS_PUBLIC_API(JSBool)
JS_StrictlyEqual(JSContext *cx, jsval v1, jsval v2, JSBool *equal);
extern JS_PUBLIC_API(JSBool)
JS_LooselyEqual(JSContext *cx, jsval v1, jsval v2, JSBool *equal);
extern JS_PUBLIC_API(JSBool)
JS_SameValue(JSContext *cx, jsval v1, jsval v2, JSBool *same);
@ -3229,7 +3238,7 @@ class JSAutoByteString {
}
~JSAutoByteString() {
js_free(mBytes);
js::UnwantedForeground::free_(mBytes);
}
/* Take ownership of the given byte array. */
@ -3246,7 +3255,7 @@ class JSAutoByteString {
}
void clear() {
js_free(mBytes);
js::UnwantedForeground::free_(mBytes);
mBytes = NULL;
}
@ -3319,7 +3328,7 @@ JS_ReadStructuredClone(JSContext *cx, const uint64 *data, size_t nbytes,
const JSStructuredCloneCallbacks *optionalCallbacks,
void *closure);
/* Note: On success, the caller is responsible for calling js_free(*datap). */
/* Note: On success, the caller is responsible for calling js::Foreground::free(*datap). */
JS_PUBLIC_API(JSBool)
JS_WriteStructuredClone(JSContext *cx, jsval v, uint64 **datap, size_t *nbytesp,
const JSStructuredCloneCallbacks *optionalCallbacks,

View File

@ -50,6 +50,8 @@
#include "jsarena.h"
#include "jsprvtd.h"
using namespace js;
#ifdef JS_ARENAMETER
static JSArenaStats *arena_stats_list;
@ -160,12 +162,12 @@ JS_ArenaAllocate(JSArenaPool *pool, size_t nb)
if (pool->quotap) {
if (gross > *pool->quotap)
return NULL;
b = (JSArena *) js_malloc(gross);
b = (JSArena *) OffTheBooks::malloc_(gross);
if (!b)
return NULL;
*pool->quotap -= gross;
} else {
b = (JSArena *) js_malloc(gross);
b = (JSArena *) OffTheBooks::malloc_(gross);
if (!b)
return NULL;
}
@ -227,12 +229,12 @@ JS_ArenaRealloc(JSArenaPool *pool, void *p, size_t size, size_t incr)
growth = gross - (a->limit - (jsuword) a);
if (growth > *pool->quotap)
return NULL;
a = (JSArena *) js_realloc(a, gross);
a = (JSArena *) OffTheBooks::realloc_(a, gross);
if (!a)
return NULL;
*pool->quotap -= growth;
} else {
a = (JSArena *) js_realloc(a, gross);
a = (JSArena *) OffTheBooks::realloc_(a, gross);
if (!a)
return NULL;
}
@ -315,7 +317,7 @@ FreeArenaList(JSArenaPool *pool, JSArena *head)
*pool->quotap += a->limit - (jsuword) a;
JS_CLEAR_ARENA(a);
JS_COUNT_ARENA(pool,--);
js_free(a);
UnwantedForeground::free_(a);
} while ((a = *ap) != NULL);
pool->current = head;
@ -354,7 +356,7 @@ JS_FinishArenaPool(JSArenaPool *pool)
JSArenaStats *stats, **statsp;
if (pool->stats.name) {
js_free(pool->stats.name);
UnwantedForeground::free_(pool->stats.name);
pool->stats.name = NULL;
}
for (statsp = &arena_stats_list; (stats = *statsp) != 0;

View File

@ -202,7 +202,7 @@ struct JSArenaPool {
if ((pool)->current == (a)) (pool)->current = &(pool)->first; \
*(pnext) = (a)->next; \
JS_CLEAR_ARENA(a); \
js_free(a); \
js::UnwantedForeground::free_(a); \
(a) = NULL; \
JS_END_MACRO

View File

@ -1154,7 +1154,7 @@ array_toSource(JSContext *cx, uintN argc, Value *vp)
if (IS_SHARP(he)) {
if (!sb.append("[]"))
goto out;
cx->free(sharpchars);
cx->free_(sharpchars);
goto make_string;
}
#endif
@ -1818,7 +1818,7 @@ js::array_sort(JSContext *cx, uintN argc, Value *vp)
* exist, allowing OS to avoiding committing RAM. See bug 330812.
*/
{
Value *vec = (Value *) cx->malloc(2 * size_t(len) * sizeof(Value));
Value *vec = (Value *) cx->malloc_(2 * size_t(len) * sizeof(Value));
if (!vec)
return false;
@ -1828,9 +1828,9 @@ js::array_sort(JSContext *cx, uintN argc, Value *vp)
public:
AutoFreeVector(JSContext *cx, Value *&vec) : cx(cx), vec(vec) { }
~AutoFreeVector() {
cx->free(vec);
cx->free_(vec);
}
} free(cx, vec);
} free_(cx, vec);
AutoArrayRooter tvr(cx, 0, vec);
@ -1940,7 +1940,7 @@ js::array_sort(JSContext *cx, uintN argc, Value *vp)
} while (i != 0);
JS_ASSERT(tvr.array == vec);
vec = (Value *) cx->realloc(vec, 4 * size_t(newlen) * sizeof(Value));
vec = (Value *) cx->realloc_(vec, 4 * size_t(newlen) * sizeof(Value));
if (!vec) {
vec = tvr.array; /* N.B. AutoFreeVector */
return false;
@ -3142,7 +3142,7 @@ js_ArrayInfo(JSContext *cx, uintN argc, jsval *vp)
if (arg.isPrimitive() ||
!(array = arg.toObjectOrNull())->isArray()) {
fprintf(stderr, "%s: not array\n", bytes);
cx->free(bytes);
cx->free_(bytes);
continue;
}
fprintf(stderr, "%s: %s (len %u", bytes,
@ -3153,7 +3153,7 @@ js_ArrayInfo(JSContext *cx, uintN argc, jsval *vp)
array->getDenseArrayCapacity());
}
fputs(")\n", stderr);
cx->free(bytes);
cx->free_(bytes);
}
JS_SET_RVAL(cx, vp, JSVAL_VOID);

View File

@ -482,7 +482,7 @@ Atomize(JSContext *cx, const jschar *chars, size_t length, uintN flags)
if (flags & ATOM_NOCOPY) {
key = js_NewString(cx, const_cast<jschar *>(chars), length);
if (!key) {
cx->free(const_cast<jschar *>(chars));
cx->free_(const_cast<jschar *>(chars));
return NULL;
}
} else {

View File

@ -606,12 +606,12 @@ class Chars {
jschar *p;
public:
Chars() : p(NULL) {}
~Chars() { if (p) cx->free(p); }
~Chars() { if (p) cx->free_(p); }
bool allocate(JSContext *cx, size_t len) {
JS_ASSERT(!p);
// We're going to null-terminate!
p = (jschar *) cx->malloc((len + 1) * sizeof(jschar));
p = (jschar *) cx->malloc_((len + 1) * sizeof(jschar));
this->cx = cx;
if (p) {
p[len] = jschar(0);

View File

@ -565,13 +565,13 @@ static JSThread *
NewThread(void *id)
{
JS_ASSERT(js_CurrentThreadId() == id);
JSThread *thread = (JSThread *) js_calloc(sizeof(JSThread));
JSThread *thread = (JSThread *) OffTheBooks::calloc_(sizeof(JSThread));
if (!thread)
return NULL;
JS_INIT_CLIST(&thread->contextList);
thread->id = id;
if (!thread->data.init()) {
js_free(thread);
Foreground::free_(thread);
return NULL;
}
return thread;
@ -590,7 +590,7 @@ DestroyThread(JSThread *thread)
JS_ASSERT(!thread->data.conservativeGC.hasStackToScan());
thread->data.finish();
js_free(thread);
Foreground::free_(thread);
}
JSThread *
@ -747,7 +747,7 @@ js_NewContext(JSRuntime *rt, size_t stackChunkSize)
* runtime list. After that it can be accessed from another thread via
* js_ContextIterator.
*/
void *mem = js_calloc(sizeof *cx);
void *mem = OffTheBooks::calloc_(sizeof *cx);
if (!mem)
return NULL;
@ -1123,21 +1123,20 @@ FreeContext(JSContext *cx)
JS_FinishArenaPool(&cx->regExpPool);
if (cx->lastMessage)
js_free(cx->lastMessage);
cx->free_(cx->lastMessage);
/* Remove any argument formatters. */
JSArgumentFormatMap *map = cx->argumentFormatMap;
while (map) {
JSArgumentFormatMap *temp = map;
map = map->next;
cx->free(temp);
cx->free_(temp);
}
JS_ASSERT(!cx->resolvingList);
/* Finally, free cx itself. */
cx->~JSContext();
js_free(cx);
Foreground::delete_(cx);
}
JSContext *
@ -1368,8 +1367,8 @@ js_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap)
warning = JSREPORT_IS_WARNING(report.flags);
ReportError(cx, message, &report, NULL, NULL);
js_free(message);
cx->free(ucmessage);
Foreground::free_(message);
Foreground::free_(ucmessage);
return warning;
}
@ -1414,7 +1413,7 @@ js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback,
* pointers later.
*/
reportp->messageArgs = (const jschar **)
cx->malloc(sizeof(jschar *) * (argCount + 1));
cx->malloc_(sizeof(jschar *) * (argCount + 1));
if (!reportp->messageArgs)
return JS_FALSE;
reportp->messageArgs[argCount] = NULL;
@ -1458,9 +1457,9 @@ js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback,
* is used once and only once in the expansion !!!
*/
reportp->ucmessage = out = (jschar *)
cx->malloc((expandedLength + 1) * sizeof(jschar));
cx->malloc_((expandedLength + 1) * sizeof(jschar));
if (!out) {
cx->free(buffer);
cx->free_(buffer);
goto error;
}
while (*fmt) {
@ -1480,7 +1479,7 @@ js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback,
}
JS_ASSERT(expandedArgs == argCount);
*out = 0;
cx->free(buffer);
cx->free_(buffer);
*messagep =
js_DeflateString(cx, reportp->ucmessage,
(size_t)(out - reportp->ucmessage));
@ -1509,7 +1508,7 @@ js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback,
const char *defaultErrorMessage
= "No error message available for error number %d";
size_t nbytes = strlen(defaultErrorMessage) + 16;
*messagep = (char *)cx->malloc(nbytes);
*messagep = (char *)cx->malloc_(nbytes);
if (!*messagep)
goto error;
JS_snprintf(*messagep, nbytes, defaultErrorMessage, errorNumber);
@ -1522,17 +1521,17 @@ error:
if (charArgs) {
i = 0;
while (reportp->messageArgs[i])
cx->free((void *)reportp->messageArgs[i++]);
cx->free_((void *)reportp->messageArgs[i++]);
}
cx->free((void *)reportp->messageArgs);
cx->free_((void *)reportp->messageArgs);
reportp->messageArgs = NULL;
}
if (reportp->ucmessage) {
cx->free((void *)reportp->ucmessage);
cx->free_((void *)reportp->ucmessage);
reportp->ucmessage = NULL;
}
if (*messagep) {
cx->free((void *)*messagep);
cx->free_((void *)*messagep);
*messagep = NULL;
}
return JS_FALSE;
@ -1564,7 +1563,7 @@ js_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallback callback,
ReportError(cx, message, &report, callback, userRef);
if (message)
cx->free(message);
cx->free_(message);
if (report.messageArgs) {
/*
* js_ExpandErrorArguments owns its messageArgs only if it had to
@ -1573,12 +1572,12 @@ js_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallback callback,
if (charArgs) {
int i = 0;
while (report.messageArgs[i])
cx->free((void *)report.messageArgs[i++]);
cx->free_((void *)report.messageArgs[i++]);
}
cx->free((void *)report.messageArgs);
cx->free_((void *)report.messageArgs);
}
if (report.ucmessage)
cx->free((void *)report.ucmessage);
cx->free_((void *)report.ucmessage);
return warning;
}
@ -1592,7 +1591,7 @@ js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *reportp)
return;
if (cx->lastMessage)
js_free(cx->lastMessage);
Foreground::free_(cx->lastMessage);
cx->lastMessage = JS_strdup(cx, message);
if (!cx->lastMessage)
return;
@ -1650,7 +1649,7 @@ js_ReportIsNullOrUndefined(JSContext *cx, intN spindex, const Value &v,
js_null_str, NULL);
}
cx->free(bytes);
cx->free_(bytes);
return ok;
}
@ -1673,7 +1672,7 @@ js_ReportMissingArg(JSContext *cx, const Value &v, uintN arg)
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_MISSING_FUN_ARG, argbuf,
bytes ? bytes : "");
cx->free(bytes);
cx->free_(bytes);
}
JSBool
@ -1692,7 +1691,7 @@ js_ReportValueErrorFlags(JSContext *cx, uintN flags, const uintN errorNumber,
ok = JS_ReportErrorFlagsAndNumber(cx, flags, js_GetErrorMessage,
NULL, errorNumber, bytes, arg1, arg2);
cx->free(bytes);
cx->free_(bytes);
return ok;
}
@ -2100,11 +2099,11 @@ JSRuntime::onOutOfMemory(void *p, size_t nbytes, JSContext *cx)
#ifdef JS_THREADSAFE
gcHelperThread.waitBackgroundSweepEnd(this);
if (!p)
p = ::js_malloc(nbytes);
p = OffTheBooks::malloc_(nbytes);
else if (p == reinterpret_cast<void *>(1))
p = ::js_calloc(nbytes);
p = OffTheBooks::calloc_(nbytes);
else
p = ::js_realloc(p, nbytes);
p = OffTheBooks::realloc_(p, nbytes);
if (p)
return p;
#endif

View File

@ -45,13 +45,6 @@
*/
#include <string.h>
/* Gross special case for Gecko, which defines malloc/calloc/free. */
#ifdef mozilla_mozalloc_macro_wrappers_h
# define JS_CNTXT_UNDEFD_MOZALLOC_WRAPPERS
/* The "anti-header" */
# include "mozilla/mozalloc_undef_macro_wrappers.h"
#endif
#include "jsprvtd.h"
#include "jsarena.h"
#include "jsclist.h"
@ -169,9 +162,9 @@ class ContextAllocPolicy
JSContext *context() const { return cx; }
/* Inline definitions below. */
void *malloc(size_t bytes);
void free(void *p);
void *realloc(void *p, size_t bytes);
void *malloc_(size_t bytes);
void free_(void *p);
void *realloc_(void *p, size_t bytes);
void reportAllocOverflow() const;
};
@ -1349,7 +1342,7 @@ struct JSRuntime {
* Call the system malloc while checking for GC memory pressure and
* reporting OOM error when cx is not null.
*/
void* malloc(size_t bytes, JSContext *cx = NULL) {
void* malloc_(size_t bytes, JSContext *cx = NULL) {
updateMallocCounter(bytes);
void *p = ::js_malloc(bytes);
return JS_LIKELY(!!p) ? p : onOutOfMemory(NULL, bytes, cx);
@ -1359,20 +1352,20 @@ struct JSRuntime {
* Call the system calloc while checking for GC memory pressure and
* reporting OOM error when cx is not null.
*/
void* calloc(size_t bytes, JSContext *cx = NULL) {
void* calloc_(size_t bytes, JSContext *cx = NULL) {
updateMallocCounter(bytes);
void *p = ::js_calloc(bytes);
return JS_LIKELY(!!p) ? p : onOutOfMemory(reinterpret_cast<void *>(1), bytes, cx);
}
void* realloc(void* p, size_t oldBytes, size_t newBytes, JSContext *cx = NULL) {
void* realloc_(void* p, size_t oldBytes, size_t newBytes, JSContext *cx = NULL) {
JS_ASSERT(oldBytes < newBytes);
updateMallocCounter(newBytes - oldBytes);
void *p2 = ::js_realloc(p, newBytes);
return JS_LIKELY(!!p2) ? p2 : onOutOfMemory(p, newBytes, cx);
}
void* realloc(void* p, size_t bytes, JSContext *cx = NULL) {
void* realloc_(void* p, size_t bytes, JSContext *cx = NULL) {
/*
* For compatibility we do not account for realloc that increases
* previously allocated memory.
@ -1383,7 +1376,13 @@ struct JSRuntime {
return JS_LIKELY(!!p2) ? p2 : onOutOfMemory(p, bytes, cx);
}
void free(void* p) { ::js_free(p); }
inline void free_(void* p) {
/* FIXME: Making this free in the background is buggy. Can it work? */
js::Foreground::free_(p);
}
JS_DECLARE_NEW_METHODS(malloc_, JS_ALWAYS_INLINE)
JS_DECLARE_DELETE_METHODS(free_, JS_ALWAYS_INLINE)
bool isGCMallocLimitReached() const { return gcMallocBytes <= 0; }
@ -1983,81 +1982,46 @@ struct JSContext
#ifdef JS_THREADSAFE
/*
* When non-null JSContext::free delegates the job to the background
* When non-null JSContext::free_ delegates the job to the background
* thread.
*/
js::GCHelperThread *gcBackgroundFree;
#endif
inline void* malloc(size_t bytes) {
return runtime->malloc(bytes, this);
inline void* malloc_(size_t bytes) {
return runtime->malloc_(bytes, this);
}
inline void* mallocNoReport(size_t bytes) {
JS_ASSERT(bytes != 0);
return runtime->malloc(bytes, NULL);
return runtime->malloc_(bytes, NULL);
}
inline void* calloc(size_t bytes) {
inline void* calloc_(size_t bytes) {
JS_ASSERT(bytes != 0);
return runtime->calloc(bytes, this);
return runtime->calloc_(bytes, this);
}
inline void* realloc(void* p, size_t bytes) {
return runtime->realloc(p, bytes, this);
inline void* realloc_(void* p, size_t bytes) {
return runtime->realloc_(p, bytes, this);
}
inline void* realloc(void* p, size_t oldBytes, size_t newBytes) {
return runtime->realloc(p, oldBytes, newBytes, this);
inline void* realloc_(void* p, size_t oldBytes, size_t newBytes) {
return runtime->realloc_(p, oldBytes, newBytes, this);
}
inline void free(void* p) {
inline void free_(void* p) {
#ifdef JS_THREADSAFE
if (gcBackgroundFree) {
gcBackgroundFree->freeLater(p);
return;
}
#endif
runtime->free(p);
runtime->free_(p);
}
/*
* In the common case that we'd like to allocate the memory for an object
* with cx->malloc/free, we cannot use overloaded C++ operators (no
* placement delete). Factor the common workaround into one place.
*/
#define CREATE_BODY(parms) \
void *memory = this->malloc(sizeof(T)); \
if (!memory) \
return NULL; \
return new(memory) T parms;
template <class T>
JS_ALWAYS_INLINE T *create() {
CREATE_BODY(())
}
template <class T, class P1>
JS_ALWAYS_INLINE T *create(const P1 &p1) {
CREATE_BODY((p1))
}
template <class T, class P1, class P2>
JS_ALWAYS_INLINE T *create(const P1 &p1, const P2 &p2) {
CREATE_BODY((p1, p2))
}
template <class T, class P1, class P2, class P3>
JS_ALWAYS_INLINE T *create(const P1 &p1, const P2 &p2, const P3 &p3) {
CREATE_BODY((p1, p2, p3))
}
#undef CREATE_BODY
template <class T>
JS_ALWAYS_INLINE void destroy(T *p) {
p->~T();
this->free(p);
}
JS_DECLARE_NEW_METHODS(malloc_, inline)
JS_DECLARE_DELETE_METHODS(free_, inline)
void purge();
@ -2723,7 +2687,7 @@ class AutoReleasePtr {
{
JS_GUARD_OBJECT_NOTIFIER_INIT;
}
~AutoReleasePtr() { cx->free(ptr); }
~AutoReleasePtr() { cx->free_(ptr); }
};
/*
@ -2745,10 +2709,10 @@ class AutoReleaseNullablePtr {
}
void reset(void *ptr2) {
if (ptr)
cx->free(ptr);
cx->free_(ptr);
ptr = ptr2;
}
~AutoReleaseNullablePtr() { if (ptr) cx->free(ptr); }
~AutoReleaseNullablePtr() { if (ptr) cx->free_(ptr); }
};
class AutoLocalNameArray {
@ -3195,21 +3159,21 @@ js_RegenerateShapeForGC(JSRuntime *rt)
namespace js {
inline void *
ContextAllocPolicy::malloc(size_t bytes)
ContextAllocPolicy::malloc_(size_t bytes)
{
return cx->malloc(bytes);
return cx->malloc_(bytes);
}
inline void
ContextAllocPolicy::free(void *p)
ContextAllocPolicy::free_(void *p)
{
cx->free(p);
cx->free_(p);
}
inline void *
ContextAllocPolicy::realloc(void *p, size_t bytes)
ContextAllocPolicy::realloc_(void *p, size_t bytes)
{
return cx->realloc(p, bytes);
return cx->realloc_(p, bytes);
}
inline void
@ -3335,8 +3299,4 @@ NewIdArray(JSContext *cx, jsint length);
#pragma warning(pop)
#endif
#ifdef JS_CNTXT_UNDEFD_MOZALLOC_WRAPPERS
# include "mozilla/mozalloc_macro_wrappers.h"
#endif
#endif /* jscntxt_h___ */

View File

@ -100,7 +100,7 @@ JSCompartment::JSCompartment(JSRuntime *rt)
JSCompartment::~JSCompartment()
{
#if ENABLE_YARR_JIT
js_delete(regExpAllocator);
Foreground::delete_(regExpAllocator);
#endif
#if defined JS_TRACER
@ -108,10 +108,10 @@ JSCompartment::~JSCompartment()
#endif
#ifdef JS_METHODJIT
js_delete(jaegerCompartment);
Foreground::delete_(jaegerCompartment);
#endif
js_delete(mathCache);
Foreground::delete_(mathCache);
#ifdef DEBUG
for (size_t i = 0; i != JS_ARRAY_LENGTH(scriptsToGC); ++i)
@ -141,12 +141,12 @@ JSCompartment::init()
#endif
#ifdef JS_TRACER
if (!InitJIT(&traceMonitor))
if (!InitJIT(&traceMonitor, rt))
return false;
#endif
#if ENABLE_YARR_JIT
regExpAllocator = js_new<JSC::ExecutableAllocator>();
regExpAllocator = rt->new_<JSC::ExecutableAllocator>();
if (!regExpAllocator)
return false;
#endif
@ -155,7 +155,7 @@ JSCompartment::init()
return false;
#ifdef JS_METHODJIT
if (!(jaegerCompartment = js_new<mjit::JaegerCompartment>()))
if (!(jaegerCompartment = rt->new_<mjit::JaegerCompartment>()))
return false;
return jaegerCompartment->Initialize();
#else
@ -574,7 +574,7 @@ MathCache *
JSCompartment::allocMathCache(JSContext *cx)
{
JS_ASSERT(!mathCache);
mathCache = js_new<MathCache>();
mathCache = cx->new_<MathCache>();
if (!mathCache)
js_ReportOutOfMemory(cx);
return mathCache;

View File

@ -2406,7 +2406,7 @@ date_toSource(JSContext *cx, uintN argc, Value *vp)
}
JSString *str = JS_NewStringCopyZ(cx, bytes);
js_free(bytes);
cx->free_(bytes);
if (!str)
return false;
vp->setString(str);

View File

@ -321,7 +321,7 @@ js_UntrapScriptCode(JSContext *cx, JSScript *script)
continue;
nbytes += (sn - notes + 1) * sizeof *sn;
code = (jsbytecode *) cx->malloc(nbytes);
code = (jsbytecode *) cx->malloc_(nbytes);
if (!code)
break;
memcpy(code, script->code, nbytes);
@ -356,7 +356,7 @@ JS_SetTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
} else {
sample = rt->debuggerMutations;
DBG_UNLOCK(rt);
trap = (JSTrap *) cx->malloc(sizeof *trap);
trap = (JSTrap *) cx->malloc_(sizeof *trap);
if (!trap)
return JS_FALSE;
trap->closure = JSVAL_NULL;
@ -380,7 +380,7 @@ JS_SetTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
trap->closure = closure;
DBG_UNLOCK(rt);
if (junk)
cx->free(junk);
cx->free_(junk);
#ifdef JS_METHODJIT
if (script->hasJITCode()) {
@ -415,7 +415,7 @@ DestroyTrapAndUnlock(JSContext *cx, JSTrap *trap)
JS_REMOVE_LINK(&trap->links);
*trap->pc = (jsbytecode)trap->op;
DBG_UNLOCK(cx->runtime);
cx->free(trap);
cx->free_(trap);
}
JS_PUBLIC_API(void)
@ -658,7 +658,7 @@ DropWatchPointAndUnlock(JSContext *cx, JSWatchPoint *wp, uintN flag, bool sweepi
}
}
cx->free(wp);
cx->free_(wp);
return ok;
}
@ -1152,7 +1152,7 @@ JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsid id,
JSWatchPoint *wp = LockedFindWatchPoint(rt, obj, propid);
if (!wp) {
DBG_UNLOCK(rt);
wp = (JSWatchPoint *) cx->malloc(sizeof *wp);
wp = (JSWatchPoint *) cx->malloc_(sizeof *wp);
if (!wp)
return false;
wp->handler = NULL;
@ -1684,7 +1684,7 @@ JS_EvaluateInStackFrame(JSContext *cx, JSStackFrame *fp,
length = (uintN) len;
ok = JS_EvaluateUCInStackFrame(cx, fp, chars, length, filename, lineno,
rval);
cx->free(chars);
cx->free_(chars);
return ok;
}
@ -1790,7 +1790,7 @@ JS_GetPropertyDescArray(JSContext *cx, JSObject *obj, JSPropertyDescArray *pda)
}
uint32 n = obj->propertyCount();
JSPropertyDesc *pd = (JSPropertyDesc *) cx->malloc(size_t(n) * sizeof(JSPropertyDesc));
JSPropertyDesc *pd = (JSPropertyDesc *) cx->malloc_(size_t(n) * sizeof(JSPropertyDesc));
if (!pd)
return JS_FALSE;
uint32 i = 0;
@ -1831,7 +1831,7 @@ JS_PutPropertyDescArray(JSContext *cx, JSPropertyDescArray *pda)
if (pd[i].flags & JSPD_ALIAS)
js_RemoveRoot(cx->runtime, &pd[i].alias);
}
cx->free(pd);
cx->free_(pd);
}
/************************************************************************/
@ -2256,7 +2256,7 @@ js_StartVtune(JSContext *cx, uintN argc, jsval *vp)
status = VTStartSampling(&params);
if (params.tb5Filename != default_filename)
cx->free(params.tb5Filename);
cx->free_(params.tb5Filename);
if (status != 0) {
if (status == VTAPI_MULTIPLE_RUNS)

View File

@ -47,7 +47,9 @@
#include "jsstdint.h"
#include "jsbit.h"
#include "jsdhash.h"
#include "jsutil.h" /* for JS_ASSERT */
#include "jsutil.h"
using namespace js;
#ifdef JS_DHASHMETER
# if defined MOZILLA_CLIENT && defined DEBUG_XXXbrendan
@ -111,13 +113,13 @@
JS_PUBLIC_API(void *)
JS_DHashAllocTable(JSDHashTable *table, uint32 nbytes)
{
return js_malloc(nbytes);
return OffTheBooks::malloc_(nbytes);
}
JS_PUBLIC_API(void)
JS_DHashFreeTable(JSDHashTable *table, void *ptr)
{
js_free(ptr);
UnwantedForeground::free_(ptr);
}
JS_PUBLIC_API(JSDHashNumber)
@ -180,7 +182,7 @@ JS_DHashFreeStringKey(JSDHashTable *table, JSDHashEntryHdr *entry)
{
const JSDHashEntryStub *stub = (const JSDHashEntryStub *)entry;
js_free((void *) stub->key);
UnwantedForeground::free_((void *) stub->key);
memset(entry, 0, table->entrySize);
}
@ -212,11 +214,11 @@ JS_NewDHashTable(const JSDHashTableOps *ops, void *data, uint32 entrySize,
{
JSDHashTable *table;
table = (JSDHashTable *) js_malloc(sizeof *table);
table = (JSDHashTable *) OffTheBooks::malloc_(sizeof *table);
if (!table)
return NULL;
if (!JS_DHashTableInit(table, ops, data, entrySize, capacity)) {
js_free(table);
Foreground::free_(table);
return NULL;
}
return table;
@ -226,7 +228,7 @@ JS_PUBLIC_API(void)
JS_DHashTableDestroy(JSDHashTable *table)
{
JS_DHashTableFinish(table);
js_free(table);
UnwantedForeground::free_(table);
}
JS_PUBLIC_API(JSBool)

View File

@ -53,6 +53,8 @@
#include "jsobjinlines.h"
using namespace js;
#ifdef IS_LITTLE_ENDIAN
#define IEEE_8087
#else
@ -77,9 +79,16 @@
#endif
*/
/*
* MALLOC gets declared external, and that doesn't work for class members, so
* wrap.
*/
inline void* dtoa_malloc(size_t size) { return OffTheBooks::malloc_(size); }
inline void dtoa_free(void* p) { return UnwantedForeground::free_(p); }
#define NO_GLOBAL_STATE
#define MALLOC js_malloc
#define FREE js_free
#define MALLOC dtoa_malloc
#define FREE dtoa_free
#include "dtoa.c"
/* Mapping of JSDToStrMode -> js_dtoa mode */
@ -327,7 +336,7 @@ js_dtobasestr(DtoaState *state, int base, double dinput)
JS_ASSERT(base >= 2 && base <= 36);
dval(d) = dinput;
buffer = (char*) js_malloc(DTOBASESTR_BUFFER_SIZE);
buffer = (char*) OffTheBooks::malloc_(DTOBASESTR_BUFFER_SIZE);
if (!buffer)
return NULL;
p = buffer;
@ -371,7 +380,7 @@ js_dtobasestr(DtoaState *state, int base, double dinput)
if (!b) {
nomem1:
Bfree(PASS_STATE b);
js_free(buffer);
UnwantedForeground::free_(buffer);
return NULL;
}
do {
@ -407,7 +416,7 @@ js_dtobasestr(DtoaState *state, int base, double dinput)
if (mlo != mhi)
Bfree(PASS_STATE mlo);
Bfree(PASS_STATE mhi);
js_free(buffer);
UnwantedForeground::free_(buffer);
return NULL;
}
JS_ASSERT(e < 0);

View File

@ -138,7 +138,7 @@ js_dtostr(DtoaState *state, char *buffer, size_t bufferSize, JSDToStrMode mode,
* not equal to itself).
*
* Return NULL if out of memory. If the result is not NULL, it must be
* released via js_free().
* released via cx->free_().
*/
char *
js_dtobasestr(DtoaState *state, int base, double d);

View File

@ -143,10 +143,10 @@ JSCodeGenerator::~JSCodeGenerator()
/* NB: non-null only after OOM. */
if (spanDeps)
parser->context->free(spanDeps);
parser->context->free_(spanDeps);
if (upvarMap.vector)
parser->context->free(upvarMap.vector);
parser->context->free_(upvarMap.vector);
}
static ptrdiff_t
@ -617,7 +617,7 @@ AddSpanDep(JSContext *cx, JSCodeGenerator *cg, jsbytecode *pc, jsbytecode *pc2,
if ((index & (index - 1)) == 0 &&
(!(sdbase = cg->spanDeps) || index >= SPANDEPS_MIN)) {
size = sdbase ? SPANDEPS_SIZE(index) : SPANDEPS_SIZE_MIN / 2;
sdbase = (JSSpanDep *) cx->realloc(sdbase, size + size);
sdbase = (JSSpanDep *) cx->realloc_(sdbase, size + size);
if (!sdbase)
return JS_FALSE;
cg->spanDeps = sdbase;
@ -1233,7 +1233,7 @@ OptimizeSpanDeps(JSContext *cx, JSCodeGenerator *cg)
* can span top-level statements, because JS lacks goto.
*/
size = SPANDEPS_SIZE(JS_BIT(JS_CeilingLog2(cg->numSpanDeps)));
cx->free(cg->spanDeps);
cx->free_(cg->spanDeps);
cg->spanDeps = NULL;
FreeJumpTargets(cg, cg->jumpTargets);
cg->jumpTargets = NULL;
@ -2301,7 +2301,7 @@ BindNameToSlot(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
UpvarCookie *vector = cg->upvarMap.vector;
uint32 length = cg->lexdeps.count;
if (!vector || cg->upvarMap.length != length) {
vector = (UpvarCookie *) js_realloc(vector, length * sizeof *vector);
vector = (UpvarCookie *) cx->realloc_(vector, length * sizeof *vector);
if (!vector) {
JS_ReportOutOfMemory(cx);
return JS_FALSE;
@ -3292,7 +3292,7 @@ EmitSwitch(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
/* Just grab 8K for the worst-case bitmap. */
intmap_bitlen = JS_BIT(16);
intmap = (jsbitmap *)
cx->malloc((JS_BIT(16) >> JS_BITS_PER_WORD_LOG2)
cx->malloc_((JS_BIT(16) >> JS_BITS_PER_WORD_LOG2)
* sizeof(jsbitmap));
if (!intmap) {
JS_ReportOutOfMemory(cx);
@ -3310,7 +3310,7 @@ EmitSwitch(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
release:
if (intmap && intmap != intmap_space)
cx->free(intmap);
cx->free_(intmap);
if (!ok)
return JS_FALSE;
@ -3454,7 +3454,7 @@ EmitSwitch(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
*/
if (tableLength != 0) {
tableSize = (size_t)tableLength * sizeof *table;
table = (JSParseNode **) cx->malloc(tableSize);
table = (JSParseNode **) cx->malloc_(tableSize);
if (!table)
return JS_FALSE;
memset(table, 0, tableSize);
@ -3619,7 +3619,7 @@ EmitSwitch(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
out:
if (table)
cx->free(table);
cx->free_(table);
if (ok) {
ok = js_PopStatementCG(cx, cg);

View File

@ -181,7 +181,7 @@ CopyErrorReport(JSContext *cx, JSErrorReport *report)
*/
mallocSize = sizeof(JSErrorReport) + argsArraySize + argsCopySize +
ucmessageSize + uclinebufSize + linebufSize + filenameSize;
cursor = (uint8 *)cx->malloc(mallocSize);
cursor = (uint8 *)cx->malloc_(mallocSize);
if (!cursor)
return NULL;
@ -320,7 +320,7 @@ InitExnPrivate(JSContext *cx, JSObject *exnObject, JSString *message,
js_ReportAllocationOverflow(cx);
return JS_FALSE;
}
priv = (JSExnPrivate *)cx->malloc(size);
priv = (JSExnPrivate *)cx->malloc_(size);
if (!priv)
return JS_FALSE;
@ -427,8 +427,8 @@ exn_finalize(JSContext *cx, JSObject *obj)
priv = GetExnPrivate(cx, obj);
if (priv) {
if (priv->errorReport)
cx->free(priv->errorReport);
cx->free(priv);
cx->free_(priv->errorReport);
cx->free_(priv);
}
}
@ -613,7 +613,7 @@ StackTraceToString(JSContext *cx, JSExnPrivate *priv)
if (stackmax >= STACK_LENGTH_LIMIT) \
goto done; \
stackmax = stackmax ? 2 * stackmax : 64; \
ptr_ = cx->realloc(stackbuf, (stackmax+1) * sizeof(jschar)); \
ptr_ = cx->realloc_(stackbuf, (stackmax+1) * sizeof(jschar)); \
if (!ptr_) \
goto bad; \
stackbuf = (jschar *) ptr_; \
@ -636,7 +636,7 @@ StackTraceToString(JSContext *cx, JSExnPrivate *priv)
goto done; \
} \
stackmax = JS_BIT(JS_CeilingLog2(stacklen + length_)); \
ptr_ = cx->realloc(stackbuf, (stackmax+1) * sizeof(jschar)); \
ptr_ = cx->realloc_(stackbuf, (stackmax+1) * sizeof(jschar)); \
if (!ptr_) \
goto bad; \
stackbuf = (jschar *) ptr_; \
@ -687,7 +687,7 @@ StackTraceToString(JSContext *cx, JSExnPrivate *priv)
* don't use JS_realloc here; simply let the oversized allocation
* be owned by the string in that rare case.
*/
void *shrunk = cx->realloc(stackbuf, (stacklen+1) * sizeof(jschar));
void *shrunk = cx->realloc_(stackbuf, (stacklen+1) * sizeof(jschar));
if (shrunk)
stackbuf = (jschar *) shrunk;
}
@ -699,7 +699,7 @@ StackTraceToString(JSContext *cx, JSExnPrivate *priv)
bad:
if (stackbuf)
cx->free(stackbuf);
cx->free_(stackbuf);
return NULL;
}
@ -827,7 +827,7 @@ exn_toString(JSContext *cx, uintN argc, Value *vp)
name_length = name->length();
message_length = message->length();
length = (name_length ? name_length + 2 : 0) + message_length;
cp = chars = (jschar *) cx->malloc((length + 1) * sizeof(jschar));
cp = chars = (jschar *) cx->malloc_((length + 1) * sizeof(jschar));
if (!chars)
return JS_FALSE;
@ -848,7 +848,7 @@ exn_toString(JSContext *cx, uintN argc, Value *vp)
result = js_NewString(cx, chars, length);
if (!result) {
cx->free(chars);
cx->free_(chars);
return JS_FALSE;
}
} else {
@ -938,7 +938,7 @@ exn_toSource(JSContext *cx, uintN argc, Value *vp)
}
}
cp = chars = (jschar *) cx->malloc((length + 1) * sizeof(jschar));
cp = chars = (jschar *) cx->malloc_((length + 1) * sizeof(jschar));
if (!chars)
return false;
@ -988,7 +988,7 @@ exn_toSource(JSContext *cx, uintN argc, Value *vp)
result = js_NewString(cx, chars, length);
if (!result) {
cx->free(chars);
cx->free_(chars);
return false;
}
vp->setString(result);

View File

@ -199,7 +199,7 @@ NewArguments(JSContext *cx, JSObject *parent, uint32 argc, JSObject &callee)
AutoShapeRooter shapeRoot(cx, emptyArgumentsShape);
ArgumentsData *data = (ArgumentsData *)
cx->malloc(offsetof(ArgumentsData, slots) + argc * sizeof(Value));
cx->malloc_(offsetof(ArgumentsData, slots) + argc * sizeof(Value));
if (!data)
return NULL;
SetValueRangeToUndefined(data->slots, argc);
@ -786,7 +786,7 @@ strictargs_enumerate(JSContext *cx, JSObject *obj)
static void
args_finalize(JSContext *cx, JSObject *obj)
{
cx->free((void *) obj->getArgsData());
cx->free_((void *) obj->getArgsData());
}
/*
@ -1989,7 +1989,7 @@ fun_finalize(JSContext *cx, JSObject *obj)
/* Cloned function objects may be flat closures with upvars to free. */
if (fun != obj) {
if (fun->isFlatClosure() && fun->script()->bindings.hasUpvars())
cx->free((void *) obj->getFlatClosureUpvars());
cx->free_((void *) obj->getFlatClosureUpvars());
return;
}
@ -2845,7 +2845,7 @@ js_AllocFlatClosure(JSContext *cx, JSFunction *fun, JSObject *scopeChain)
if (nslots == 0)
return closure;
Value *upvars = (Value *) cx->malloc(nslots * sizeof(Value));
Value *upvars = (Value *) cx->malloc_(nslots * sizeof(Value));
if (!upvars)
return NULL;

View File

@ -48,7 +48,6 @@
*
* XXX swizzle page to freelist for better locality of reference
*/
#include <stdlib.h> /* for free */
#include <math.h>
#include <string.h> /* for memset used when DEBUG */
#include "jstypes.h"
@ -403,7 +402,7 @@ ReleaseGCChunk(JSRuntime *rt, jsuword chunk)
#endif
JS_ASSERT(rt->gcStats.nchunks != 0);
METER(rt->gcStats.nchunks--);
rt->gcChunkAllocator->free(p);
rt->gcChunkAllocator->free_(p);
}
inline Chunk *
@ -427,7 +426,7 @@ ReleaseGCChunk(JSRuntime *rt, Chunk *p)
#endif
JS_ASSERT(rt->gcStats.nchunks != 0);
METER(rt->gcStats.nchunks--);
rt->gcChunkAllocator->free(p);
rt->gcChunkAllocator->free_(p);
}
static Chunk *
@ -572,8 +571,6 @@ js_InitGC(JSRuntime *rt, uint32 maxbytes)
rt->gcTriggerFactor = uint32(100.0f * GC_HEAP_GROWTH_FACTOR);
rt->atomsCompartment->setGCLastBytes(8192);
/*
* The assigned value prevents GC from running when GC memory is too low
* (during JS engine start).
@ -869,7 +866,7 @@ js_FinishGC(JSRuntime *rt)
for (JSCompartment **c = rt->compartments.begin(); c != rt->compartments.end(); ++c) {
JSCompartment *comp = *c;
comp->finishArenaLists();
js_delete(comp);
Foreground::delete_(comp);
}
rt->compartments.clear();
rt->atomsCompartment = NULL;
@ -1808,7 +1805,7 @@ js_FinalizeStringRT(JSRuntime *rt, JSString *str)
jschar *chars = const_cast<jschar *>(str->asFlat().chars());
if (thingKind == FINALIZE_STRING) {
rt->stringMemoryUsed -= str->length() * 2;
rt->free(chars);
rt->free_(chars);
} else if (thingKind == FINALIZE_EXTERNAL_STRING) {
((JSExternalString *)str)->finalize();
}
@ -2050,7 +2047,7 @@ GCHelperThread::replenishAndFreeLater(void *ptr)
do {
if (freeCursor && !freeVector.append(freeCursorEnd - FREE_ARRAY_LENGTH))
break;
freeCursor = (void **) js_malloc(FREE_ARRAY_SIZE);
freeCursor = (void **) OffTheBooks::malloc_(FREE_ARRAY_SIZE);
if (!freeCursor) {
freeCursorEnd = NULL;
break;
@ -2059,7 +2056,7 @@ GCHelperThread::replenishAndFreeLater(void *ptr)
*freeCursor++ = ptr;
return;
} while (false);
js_free(ptr);
Foreground::free_(ptr);
}
void
@ -2132,7 +2129,7 @@ SweepCompartments(JSContext *cx, JSGCInvocationKind gckind)
(void) callback(cx, compartment, JSCOMPARTMENT_DESTROY);
if (compartment->principals)
JSPRINCIPALS_DROP(cx, compartment->principals);
js_delete(compartment);
cx->delete_(compartment);
continue;
}
*write++ = compartment;
@ -2724,9 +2721,9 @@ JSCompartment *
NewCompartment(JSContext *cx, JSPrincipals *principals)
{
JSRuntime *rt = cx->runtime;
JSCompartment *compartment = js_new<JSCompartment>(rt);
JSCompartment *compartment = cx->new_<JSCompartment>(rt);
if (!compartment || !compartment->init()) {
js_delete(compartment);
Foreground::delete_(compartment);
JS_ReportOutOfMemory(cx);
return NULL;
}
@ -2743,6 +2740,7 @@ NewCompartment(JSContext *cx, JSPrincipals *principals)
if (!rt->compartments.append(compartment)) {
AutoUnlockGC unlock(rt);
Foreground::delete_(compartment);
JS_ReportOutOfMemory(cx);
return NULL;
}
@ -2752,7 +2750,7 @@ NewCompartment(JSContext *cx, JSPrincipals *principals)
if (callback && !callback(cx, compartment, JSCOMPARTMENT_NEW)) {
AutoLockGC lock(rt);
rt->compartments.popBack();
js_delete(compartment);
Foreground::delete_(compartment);
return NULL;
}
return compartment;

View File

@ -40,13 +40,6 @@
#ifndef jsgc_h___
#define jsgc_h___
/* Gross special case for Gecko, which defines malloc/calloc/free. */
#ifdef mozilla_mozalloc_macro_wrappers_h
# define JS_GC_UNDEFD_MOZALLOC_WRAPPERS
/* The "anti-header" */
# include "mozilla/mozalloc_undef_macro_wrappers.h"
#endif
/*
* JS Garbage Collector.
*/
@ -904,8 +897,8 @@ class GCHelperThread {
static void freeElementsAndArray(void **array, void **end) {
JS_ASSERT(array <= end);
for (void **p = array; p != end; ++p)
js_free(*p);
js_free(array);
js::Foreground::free_(*p);
js::Foreground::free_(array);
}
static void threadMain(void* arg);
@ -1098,8 +1091,4 @@ JSObject::getCompartment() const
return compartment();
}
#ifdef JS_GC_UNDEFD_MOZALLOC_WRAPPERS
# include "mozilla/mozalloc_macro_wrappers.h"
#endif
#endif /* jsgc_h___ */

View File

@ -70,7 +70,7 @@ class GCChunkAllocator {
return chunk;
}
void free(void *chunk) {
void free_(void *chunk) {
JS_ASSERT(chunk);
JS_ASSERT(!(reinterpret_cast<jsuword>(chunk) & GC_CHUNK_MASK));
doFree(chunk);

View File

@ -173,8 +173,7 @@ NewFinalizableGCThing(JSContext *cx, unsigned thingKind)
#ifdef JS_THREADSAFE
JS_ASSERT_IF((cx->compartment == cx->runtime->atomsCompartment),
(thingKind == js::gc::FINALIZE_STRING) ||
(thingKind == js::gc::FINALIZE_SHORT_STRING) ||
(thingKind == js::gc::FINALIZE_SHAPE));
(thingKind == js::gc::FINALIZE_SHORT_STRING));
#endif
METER(cx->compartment->compartmentStats[thingKind].alloc++);

View File

@ -48,6 +48,8 @@
#include "jsutil.h"
#include "jshash.h"
using namespace js;
/* Compute the number of buckets in ht */
#define NBUCKETS(ht) JS_BIT(JS_HASH_BITS - (ht)->shift)
@ -67,26 +69,26 @@
static void *
DefaultAllocTable(void *pool, size_t size)
{
return js_malloc(size);
return OffTheBooks::malloc_(size);
}
static void
DefaultFreeTable(void *pool, void *item, size_t size)
{
js_free(item);
UnwantedForeground::free_(item);
}
static JSHashEntry *
DefaultAllocEntry(void *pool, const void *key)
{
return (JSHashEntry*) js_malloc(sizeof(JSHashEntry));
return (JSHashEntry*) OffTheBooks::malloc_(sizeof(JSHashEntry));
}
static void
DefaultFreeEntry(void *pool, JSHashEntry *he, uintN flag)
{
if (flag == HT_FREE_ENTRY)
js_free(he);
UnwantedForeground::free_(he);
}
static JSHashAllocOps defaultHashAllocOps = {

View File

@ -300,7 +300,7 @@ class HashTable : private AllocPolicy
static Entry *createTable(AllocPolicy &alloc, uint32 capacity)
{
Entry *newTable = (Entry *)alloc.malloc(capacity * sizeof(Entry));
Entry *newTable = (Entry *)alloc.malloc_(capacity * sizeof(Entry));
if (!newTable)
return NULL;
for (Entry *e = newTable, *end = e + capacity; e != end; ++e)
@ -312,7 +312,7 @@ class HashTable : private AllocPolicy
{
for (Entry *e = oldTable, *end = e + capacity; e != end; ++e)
e->~Entry();
alloc.free(oldTable);
alloc.free_(oldTable);
}
public:

View File

@ -1084,6 +1084,80 @@ HasInstance(JSContext *cx, JSObject *obj, const Value *v, JSBool *bp)
return JS_FALSE;
}
bool
LooselyEqual(JSContext *cx, const Value &lval, const Value &rval, JSBool *result)
{
#if JS_HAS_XML_SUPPORT
if (JS_UNLIKELY(lval.isObject() && lval.toObject().isXML()) ||
(rval.isObject() && rval.toObject().isXML())) {
return js_TestXMLEquality(cx, lval, rval, result);
}
#endif
if (SameType(lval, rval)) {
if (lval.isString()) {
JSString *l = lval.toString();
JSString *r = rval.toString();
return EqualStrings(cx, l, r, result);
}
if (lval.isDouble()) {
double l = lval.toDouble(), r = rval.toDouble();
*result = JSDOUBLE_COMPARE(l, ==, r, false);
return true;
}
if (lval.isObject()) {
JSObject *l = &lval.toObject();
JSObject *r = &rval.toObject();
l->assertSpecialEqualitySynced();
if (EqualityOp eq = l->getClass()->ext.equality) {
return eq(cx, l, &rval, result);
}
*result = l == r;
return true;
}
*result = lval.payloadAsRawUint32() == rval.payloadAsRawUint32();
return true;
}
if (lval.isNullOrUndefined()) {
*result = rval.isNullOrUndefined();
return true;
}
if (rval.isNullOrUndefined()) {
*result = false;
return true;
}
Value lvalue = lval;
Value rvalue = rval;
if (lvalue.isObject() && !DefaultValue(cx, &lvalue.toObject(), JSTYPE_VOID, &lvalue))
return false;
if (rvalue.isObject() && !DefaultValue(cx, &rvalue.toObject(), JSTYPE_VOID, &rvalue))
return false;
if (lvalue.isString() && rvalue.isString()) {
JSString *l = lvalue.toString();
JSString *r = rvalue.toString();
return EqualStrings(cx, l, r, result);
}
double l, r;
if (!ValueToNumber(cx, lvalue, &l) ||
!ValueToNumber(cx, rvalue, &r)) {
return false;
}
*result = JSDOUBLE_COMPARE(l, ==, r, false);
return true;
}
bool
StrictlyEqual(JSContext *cx, const Value &lref, const Value &rref, JSBool *equal)
{
@ -1508,7 +1582,7 @@ js_LogOpcode(JSContext *cx)
fprintf(logfp, "%s %s",
(n == -ndefs) ? " output:" : ",",
bytes);
cx->free(bytes);
cx->free_(bytes);
} else {
JS_ClearPendingException(cx);
}
@ -1560,7 +1634,7 @@ js_LogOpcode(JSContext *cx)
fprintf(logfp, "%s %s",
(n == -nuses) ? " inputs:" : ",",
bytes);
cx->free(bytes);
cx->free_(bytes);
} else {
JS_ClearPendingException(cx);
}
@ -1649,7 +1723,7 @@ js_DumpOpMeters()
# define SIGNIFICANT(count,total) (200. * (count) >= (total))
graph = (Edge *) js_calloc(nedges * sizeof graph[0]);
graph = (Edge *) OffTheBooks::calloc_(nedges * sizeof graph[0]);
if (!graph)
return;
for (i = nedges = 0; i < JSOP_LIMIT; i++) {
@ -1680,7 +1754,7 @@ js_DumpOpMeters()
graph[i].from, graph[i].to,
(unsigned long)graph[i].count, style);
}
js_free(graph);
cx->free_(graph);
fputs("}\n", fp);
fclose(fp);
@ -3373,94 +3447,28 @@ END_CASE(JSOP_BITAND)
#undef BITWISE_OP
/*
* NB: These macros can't use JS_BEGIN_MACRO/JS_END_MACRO around their bodies
* because they begin if/else chains, so callers must not put semicolons after
* the call expressions!
*/
#if JS_HAS_XML_SUPPORT
#define XML_EQUALITY_OP(OP) \
if ((lval.isObject() && lval.toObject().isXML()) || \
(rval.isObject() && rval.toObject().isXML())) { \
if (!js_TestXMLEquality(cx, lval, rval, &cond)) \
goto error; \
cond = cond OP JS_TRUE; \
} else
#else
#define XML_EQUALITY_OP(OP) /* nothing */
#endif
#define EQUALITY_OP(OP, IFNAN) \
#define EQUALITY_OP(OP) \
JS_BEGIN_MACRO \
JSBool cond; \
Value rval = regs.sp[-1]; \
Value lval = regs.sp[-2]; \
XML_EQUALITY_OP(OP) \
if (SameType(lval, rval)) { \
if (lval.isString()) { \
JSString *l = lval.toString(), *r = rval.toString(); \
JSBool equal; \
if (!EqualStrings(cx, l, r, &equal)) \
goto error; \
cond = equal OP JS_TRUE; \
} else if (lval.isDouble()) { \
double l = lval.toDouble(), r = rval.toDouble(); \
cond = JSDOUBLE_COMPARE(l, OP, r, IFNAN); \
} else if (lval.isObject()) { \
JSObject *l = &lval.toObject(), *r = &rval.toObject(); \
l->assertSpecialEqualitySynced(); \
if (EqualityOp eq = l->getClass()->ext.equality) { \
if (!eq(cx, l, &rval, &cond)) \
JSBool cond; \
if (!LooselyEqual(cx, lval, rval, &cond)) \
goto error; \
cond = cond OP JS_TRUE; \
} else { \
cond = l OP r; \
} \
} else { \
cond = lval.payloadAsRawUint32() OP rval.payloadAsRawUint32();\
} \
} else { \
if (lval.isNullOrUndefined()) { \
cond = rval.isNullOrUndefined() OP true; \
} else if (rval.isNullOrUndefined()) { \
cond = true OP false; \
} else { \
if (lval.isObject()) \
DEFAULT_VALUE(cx, -2, JSTYPE_VOID, lval); \
if (rval.isObject()) \
DEFAULT_VALUE(cx, -1, JSTYPE_VOID, rval); \
if (lval.isString() && rval.isString()) { \
JSString *l = lval.toString(), *r = rval.toString(); \
JSBool equal; \
if (!EqualStrings(cx, l, r, &equal)) \
goto error; \
cond = equal OP JS_TRUE; \
} else { \
double l, r; \
if (!ValueToNumber(cx, lval, &l) || \
!ValueToNumber(cx, rval, &r)) { \
goto error; \
} \
cond = JSDOUBLE_COMPARE(l, OP, r, IFNAN); \
} \
} \
} \
TRY_BRANCH_AFTER_COND(cond, 2); \
regs.sp--; \
regs.sp[-1].setBoolean(cond); \
JS_END_MACRO
BEGIN_CASE(JSOP_EQ)
EQUALITY_OP(==, false);
EQUALITY_OP(==);
END_CASE(JSOP_EQ)
BEGIN_CASE(JSOP_NE)
EQUALITY_OP(!=, true);
EQUALITY_OP(!=);
END_CASE(JSOP_NE)
#undef EQUALITY_OP
#undef XML_EQUALITY_OP
#undef EXTENDED_EQUALITY_OP
#define STRICT_EQUALITY_OP(OP, COND) \
JS_BEGIN_MACRO \

View File

@ -1077,6 +1077,9 @@ CheckRedeclaration(JSContext *cx, JSObject *obj, jsid id, uintN attrs);
extern bool
StrictlyEqual(JSContext *cx, const Value &lval, const Value &rval, JSBool *equal);
extern bool
LooselyEqual(JSContext *cx, const Value &lval, const Value &rval, JSBool *equal);
/* === except that NaN is the same as NaN and -0 is not the same as +0. */
extern bool
SameValue(JSContext *cx, const Value &v1, const Value &v2, JSBool *same);

View File

@ -127,7 +127,7 @@ iterator_finalize(JSContext *cx, JSObject *obj)
NativeIterator *ni = obj->getNativeIterator();
if (ni) {
cx->free(ni);
cx->free_(ni);
obj->setNativeIterator(NULL);
}
}
@ -337,7 +337,7 @@ VectorToIdArray(JSContext *cx, AutoIdVector &props, JSIdArray **idap)
size_t len = props.length();
size_t idsz = len * sizeof(jsid);
size_t sz = (sizeof(JSIdArray) - sizeof(jsid)) + idsz;
JSIdArray *ida = static_cast<JSIdArray *>(cx->malloc(sz));
JSIdArray *ida = static_cast<JSIdArray *>(cx->malloc_(sz));
if (!ida)
return false;
@ -441,7 +441,7 @@ NativeIterator::allocateIterator(JSContext *cx, uint32 slength, const AutoIdVect
{
size_t plength = props.length();
NativeIterator *ni = (NativeIterator *)
cx->malloc(sizeof(NativeIterator) + plength * sizeof(jsid) + slength * sizeof(uint32));
cx->malloc_(sizeof(NativeIterator) + plength * sizeof(jsid) + slength * sizeof(uint32));
if (!ni)
return NULL;
ni->props_array = ni->props_cursor = (jsid *) (ni + 1);
@ -1069,7 +1069,7 @@ generator_finalize(JSContext *cx, JSObject *obj)
JS_ASSERT(gen->state == JSGEN_NEWBORN ||
gen->state == JSGEN_CLOSED ||
gen->state == JSGEN_OPEN);
cx->free(gen);
cx->free_(gen);
}
static void
@ -1166,7 +1166,7 @@ js_NewGenerator(JSContext *cx)
VALUES_PER_STACK_FRAME +
stackfp->numSlots()) * sizeof(Value);
JSGenerator *gen = (JSGenerator *) cx->malloc(nbytes);
JSGenerator *gen = (JSGenerator *) cx->malloc_(nbytes);
if (!gen)
return NULL;

View File

@ -305,7 +305,7 @@ struct JSFatLock {
};
typedef struct JSFatLockTable {
JSFatLock *free;
JSFatLock *free_;
JSFatLock *taken;
} JSFatLockTable;
@ -364,7 +364,7 @@ js_FinishLock(JSThinLock *tl)
static JSFatLock *
NewFatlock()
{
JSFatLock *fl = (JSFatLock *)js_malloc(sizeof(JSFatLock)); /* for now */
JSFatLock *fl = (JSFatLock *) OffTheBooks::malloc_(sizeof(JSFatLock)); /* for now */
if (!fl) return NULL;
fl->susp = 0;
fl->next = NULL;
@ -379,7 +379,7 @@ DestroyFatlock(JSFatLock *fl)
{
PR_DestroyLock(fl->slock);
PR_DestroyCondVar(fl->svar);
js_free(fl);
UnwantedForeground::free_(fl);
}
static JSFatLock *
@ -418,15 +418,15 @@ GetFatlock(void *id)
JSFatLock *m;
uint32 i = GLOBAL_LOCK_INDEX(id);
if (fl_list_table[i].free == NULL) {
if (fl_list_table[i].free_ == NULL) {
#ifdef DEBUG
if (fl_list_table[i].taken)
printf("Ran out of fat locks!\n");
#endif
fl_list_table[i].free = ListOfFatlocks(fl_list_chunk_len);
fl_list_table[i].free_ = ListOfFatlocks(fl_list_chunk_len);
}
m = fl_list_table[i].free;
fl_list_table[i].free = m->next;
m = fl_list_table[i].free_;
fl_list_table[i].free_ = m->next;
m->susp = 0;
m->next = fl_list_table[i].taken;
m->prevp = &fl_list_table[i].taken;
@ -450,8 +450,8 @@ PutFatlock(JSFatLock *m, void *id)
/* Insert m in fl_list_table[i].free. */
i = GLOBAL_LOCK_INDEX(id);
m->next = fl_list_table[i].free;
fl_list_table[i].free = m;
m->next = fl_list_table[i].free_;
fl_list_table[i].free_ = m;
}
#endif /* !NSPR_LOCK */
@ -473,7 +473,7 @@ js_SetupLocks(int listc, int globc)
global_locks_log2 = JS_CeilingLog2(globc);
global_locks_mask = JS_BITMASK(global_locks_log2);
global_lock_count = JS_BIT(global_locks_log2);
global_locks = (PRLock **) js_malloc(global_lock_count * sizeof(PRLock*));
global_locks = (PRLock **) OffTheBooks::malloc_(global_lock_count * sizeof(PRLock*));
if (!global_locks)
return JS_FALSE;
for (i = 0; i < global_lock_count; i++) {
@ -484,14 +484,14 @@ js_SetupLocks(int listc, int globc)
return JS_FALSE;
}
}
fl_list_table = (JSFatLockTable *) js_malloc(i * sizeof(JSFatLockTable));
fl_list_table = (JSFatLockTable *) OffTheBooks::malloc_(i * sizeof(JSFatLockTable));
if (!fl_list_table) {
js_CleanupLocks();
return JS_FALSE;
}
fl_list_table_len = global_lock_count;
for (i = 0; i < global_lock_count; i++)
fl_list_table[i].free = fl_list_table[i].taken = NULL;
fl_list_table[i].free_ = fl_list_table[i].taken = NULL;
fl_list_chunk_len = listc;
#endif /* !NSPR_LOCK */
return JS_TRUE;
@ -506,7 +506,7 @@ js_CleanupLocks()
if (global_locks) {
for (i = 0; i < global_lock_count; i++)
PR_DestroyLock(global_locks[i]);
js_free(global_locks);
UnwantedForeground::free_(global_locks);
global_locks = NULL;
global_lock_count = 1;
global_locks_log2 = 0;
@ -514,12 +514,12 @@ js_CleanupLocks()
}
if (fl_list_table) {
for (i = 0; i < fl_list_table_len; i++) {
DeleteListOfFatlocks(fl_list_table[i].free);
fl_list_table[i].free = NULL;
DeleteListOfFatlocks(fl_list_table[i].free_);
fl_list_table[i].free_ = NULL;
DeleteListOfFatlocks(fl_list_table[i].taken);
fl_list_table[i].taken = NULL;
}
js_free(fl_list_table);
UnwantedForeground::free_(fl_list_table);
fl_list_table = NULL;
fl_list_table_len = 0;
}

View File

@ -113,7 +113,7 @@ static bool
ComputeAccurateDecimalInteger(JSContext *cx, const jschar *start, const jschar *end, jsdouble *dp)
{
size_t length = end - start;
char *cstr = static_cast<char *>(cx->malloc(length + 1));
char *cstr = static_cast<char *>(cx->malloc_(length + 1));
if (!cstr)
return false;
@ -129,12 +129,12 @@ ComputeAccurateDecimalInteger(JSContext *cx, const jschar *start, const jschar *
*dp = js_strtod_harder(JS_THREAD_DATA(cx)->dtoaState, cstr, &estr, &err);
if (err == JS_DTOA_ENOMEM) {
JS_ReportOutOfMemory(cx);
cx->free(cstr);
cx->free_(cstr);
return false;
}
if (err == JS_DTOA_ERANGE && *dp == HUGE_VAL)
*dp = js_PositiveInfinity;
cx->free(cstr);
cx->free_(cstr);
return true;
}
@ -597,7 +597,7 @@ ToCStringBuf::ToCStringBuf() :dbuf(NULL)
ToCStringBuf::~ToCStringBuf()
{
if (dbuf)
js_free(dbuf);
UnwantedForeground::free_(dbuf);
}
JSString * JS_FASTCALL
@ -793,7 +793,7 @@ num_toLocaleString(JSContext *cx, uintN argc, Value *vp)
}
tmpGroup--;
buf = (char *)cx->malloc(buflen + 1);
buf = (char *)cx->malloc_(buflen + 1);
if (!buf)
return JS_FALSE;
@ -829,12 +829,12 @@ num_toLocaleString(JSContext *cx, uintN argc, Value *vp)
if (cx->localeCallbacks && cx->localeCallbacks->localeToUnicode) {
JSBool ok = cx->localeCallbacks->localeToUnicode(cx, buf, Jsvalify(vp));
cx->free(buf);
cx->free_(buf);
return ok;
}
str = js_NewStringCopyN(cx, buf, buflen);
cx->free(buf);
cx->free_(buf);
if (!str)
return JS_FALSE;
@ -1054,9 +1054,9 @@ js_FinishRuntimeNumberState(JSContext *cx)
{
JSRuntime *rt = cx->runtime;
cx->free((void *) rt->thousandsSeparator);
cx->free((void *) rt->decimalSeparator);
cx->free((void *) rt->numGrouping);
cx->free_((void *) rt->thousandsSeparator);
cx->free_((void *) rt->decimalSeparator);
cx->free_((void *) rt->numGrouping);
rt->thousandsSeparator = rt->decimalSeparator = rt->numGrouping = NULL;
}
@ -1415,7 +1415,7 @@ js_strtod(JSContext *cx, const jschar *s, const jschar *send,
/* Use cbuf to avoid malloc */
if (length >= sizeof cbuf) {
cstr = (char *) cx->malloc(length + 1);
cstr = (char *) cx->malloc_(length + 1);
if (!cstr)
return JS_FALSE;
} else {
@ -1446,7 +1446,7 @@ js_strtod(JSContext *cx, const jschar *s, const jschar *send,
i = estr - cstr;
if (cstr != cbuf)
cx->free(cstr);
cx->free_(cstr);
*ep = i ? s1 + i : s;
*dp = d;
return JS_TRUE;

View File

@ -224,7 +224,7 @@ struct ToCStringBuf
*/
static const size_t sbufSize = 34;
char sbuf[sbufSize];
char *dbuf; /* must be allocated with js_malloc() */
char *dbuf;
ToCStringBuf();
~ToCStringBuf();

View File

@ -385,7 +385,7 @@ out:
ida = JS_Enumerate(cx, obj);
if (!ida) {
if (*sp) {
cx->free(*sp);
cx->free_(*sp);
*sp = NULL;
}
goto bad;
@ -525,7 +525,7 @@ obj_toSource(JSContext *cx, uintN argc, Value *vp)
if (!chars) {
/* If outermost, allocate 4 + 1 for "({})" and the terminator. */
chars = (jschar *) cx->runtime->malloc(((outermost ? 4 : 2) + 1) * sizeof(jschar));
chars = (jschar *) cx->malloc_(((outermost ? 4 : 2) + 1) * sizeof(jschar));
nchars = 0;
if (!chars)
goto error;
@ -536,9 +536,9 @@ obj_toSource(JSContext *cx, uintN argc, Value *vp)
MAKE_SHARP(he);
nchars = js_strlen(chars);
chars = (jschar *)
js_realloc((ochars = chars), (nchars + 2 + 1) * sizeof(jschar));
cx->realloc_((ochars = chars), (nchars + 2 + 1) * sizeof(jschar));
if (!chars) {
js_free(ochars);
Foreground::free_(ochars);
goto error;
}
if (outermost) {
@ -739,7 +739,7 @@ obj_toSource(JSContext *cx, uintN argc, Value *vp)
goto overflow;
/* Allocate 1 + 1 at end for closing brace and terminating 0. */
chars = (jschar *) js_realloc((ochars = chars), curlen * sizeof(jschar));
chars = (jschar *) cx->realloc_((ochars = chars), curlen * sizeof(jschar));
if (!chars) {
chars = ochars;
goto overflow;
@ -773,7 +773,7 @@ obj_toSource(JSContext *cx, uintN argc, Value *vp)
nchars += vlength;
if (vsharp)
cx->free(vsharp);
cx->free_(vsharp);
}
}
@ -787,7 +787,7 @@ obj_toSource(JSContext *cx, uintN argc, Value *vp)
if (!ok) {
if (chars)
js_free(chars);
Foreground::free_(chars);
goto out;
}
@ -799,7 +799,7 @@ obj_toSource(JSContext *cx, uintN argc, Value *vp)
make_string:
str = js_NewString(cx, chars, nchars);
if (!str) {
js_free(chars);
cx->free_(chars);
ok = JS_FALSE;
goto out;
}
@ -809,8 +809,8 @@ obj_toSource(JSContext *cx, uintN argc, Value *vp)
return ok;
overflow:
cx->free(vsharp);
js_free(chars);
cx->free_(vsharp);
cx->free_(chars);
chars = NULL;
goto error;
}
@ -826,7 +826,7 @@ obj_toStringHelper(JSContext *cx, JSObject *obj)
const char *clazz = obj->getClass()->name;
size_t nchars = 9 + strlen(clazz); /* 9 for "[object ]" */
jschar *chars = (jschar *) cx->malloc((nchars + 1) * sizeof(jschar));
jschar *chars = (jschar *) cx->malloc_((nchars + 1) * sizeof(jschar));
if (!chars)
return NULL;
@ -841,7 +841,7 @@ obj_toStringHelper(JSContext *cx, JSObject *obj)
JSString *str = js_NewString(cx, chars, nchars);
if (!str)
cx->free(chars);
cx->free_(chars);
return str;
}
@ -3998,7 +3998,7 @@ JSObject::allocSlots(JSContext *cx, size_t newcap)
return false;
}
Value *tmpslots = (Value*) cx->malloc(newcap * sizeof(Value));
Value *tmpslots = (Value*) cx->malloc_(newcap * sizeof(Value));
if (!tmpslots)
return false; /* Leave slots at inline buffer. */
slots = tmpslots;
@ -4046,7 +4046,7 @@ JSObject::growSlots(JSContext *cx, size_t newcap)
if (!hasSlotsArray())
return allocSlots(cx, actualCapacity);
Value *tmpslots = (Value*) cx->realloc(slots, oldcap * sizeof(Value), actualCapacity * sizeof(Value));
Value *tmpslots = (Value*) cx->realloc_(slots, oldcap * sizeof(Value), actualCapacity * sizeof(Value));
if (!tmpslots)
return false; /* Leave dslots as its old size. */
slots = tmpslots;
@ -4076,7 +4076,7 @@ JSObject::shrinkSlots(JSContext *cx, size_t newcap)
if (newcap < numFixedSlots())
newcap = numFixedSlots();
Value *tmpslots = (Value*) cx->realloc(slots, newcap * sizeof(Value));
Value *tmpslots = (Value*) cx->realloc_(slots, newcap * sizeof(Value));
if (!tmpslots)
return; /* Leave slots at its old size. */
slots = tmpslots;

View File

@ -41,13 +41,6 @@
#ifndef jsobj_h___
#define jsobj_h___
/* Gross special case for Gecko, which defines malloc/calloc/free. */
#ifdef mozilla_mozalloc_macro_wrappers_h
# define JS_OBJ_UNDEFD_MOZALLOC_WRAPPERS
/* The "anti-header" */
# include "mozilla/mozalloc_undef_macro_wrappers.h"
#endif
/*
* JS object definitions.
*
@ -1984,8 +1977,4 @@ IsAnyBuiltinEval(JSFunction *fun);
}
#ifdef JS_OBJ_UNDEFD_MOZALLOC_WRAPPERS
# include "mozilla/mozalloc_macro_wrappers.h"
#endif
#endif /* jsobj_h___ */

View File

@ -800,7 +800,7 @@ JSObject::finish(JSContext *cx)
if (hasSlotsArray())
freeSlotsArray(cx);
if (emptyShapes)
cx->free(emptyShapes);
cx->free_(emptyShapes);
}
inline bool
@ -827,7 +827,7 @@ inline void
JSObject::freeSlotsArray(JSContext *cx)
{
JS_ASSERT(hasSlotsArray());
cx->free(slots);
cx->free_(slots);
}
inline void

View File

@ -715,7 +715,7 @@ js_BeginJSONParse(JSContext *cx, Value *rootVal, bool suppressErrors /*= false*/
if (!arr)
return NULL;
JSONParser *jp = cx->create<JSONParser>(cx);
JSONParser *jp = cx->new_<JSONParser>(cx);
if (!jp)
return NULL;
@ -771,7 +771,7 @@ js_FinishJSONParse(JSContext *cx, JSONParser *jp, const Value &reviver)
ok = Revive(cx, reviver, vp);
}
cx->destroy(jp);
cx->delete_(jp);
return ok;
}

View File

@ -262,7 +262,7 @@ public:
ptrdiff_t delta = newPC - origPC;
if (delta) {
jsbytecode *oldCode = script->code - delta;
cx->free(script->code);
cx->free_(script->code);
script->code = oldCode;
script->main -= delta;
}
@ -697,7 +697,7 @@ Sprint(Sprinter *sp, const char *format, ...)
return -1;
}
offset = SprintCString(sp, bp);
js_free(bp);
sp->context->free_(bp);
return offset;
}
@ -829,7 +829,7 @@ js_NewPrinter(JSContext *cx, const char *name, JSFunction *fun,
{
JSPrinter *jp;
jp = (JSPrinter *) cx->malloc(sizeof(JSPrinter));
jp = (JSPrinter *) cx->malloc_(sizeof(JSPrinter));
if (!jp)
return NULL;
INIT_SPRINTER(cx, &jp->sprinter, &jp->pool, 0);
@ -857,7 +857,7 @@ void
js_DestroyPrinter(JSPrinter *jp)
{
JS_FinishArenaPool(&jp->pool);
jp->sprinter.context->free(jp);
jp->sprinter.context->free_(jp);
}
JSString *
@ -929,7 +929,7 @@ js_printf(JSPrinter *jp, const char *format, ...)
/* Allocate temp space, convert format, and put. */
bp = JS_vsmprintf(format, ap); /* XXX vsaprintf */
if (fp) {
jp->sprinter.context->free(fp);
jp->sprinter.context->free_(fp);
format = NULL;
}
if (!bp) {
@ -941,7 +941,7 @@ js_printf(JSPrinter *jp, const char *format, ...)
cc = strlen(bp);
if (SprintPut(&jp->sprinter, bp, (size_t)cc) < 0)
cc = -1;
js_free(bp);
jp->sprinter.context->free_(bp);
va_end(ap);
return cc;
@ -1027,7 +1027,7 @@ GetOff(SprintStack *ss, uintN i)
if (off < 0)
off = 0;
ss->offsets[i] = off;
ss->sprinter.context->free(bytes);
ss->sprinter.context->free_(bytes);
return off;
}
if (!ss->sprinter.base && SprintPut(&ss->sprinter, "", 0) >= 0) {
@ -2590,14 +2590,14 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
len = 0;
if (!Decompile(ss, done, pc - done, JSOP_POP)) {
cx->free((char *)lval);
cx->free_((char *)lval);
return NULL;
}
/* Pop Decompile result and print comma expression. */
rval = POP_STR();
todo = Sprint(&ss->sprinter, "%s, %s", lval, rval);
cx->free((char *)lval);
cx->free_((char *)lval);
break;
case SRC_HIDDEN:
@ -2629,7 +2629,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
/* Set saveop to reflect what we will push. */
saveop = JSOP_LEAVEBLOCKEXPR;
if (!Decompile(ss, pc, len, saveop)) {
cx->free((char *)lval);
cx->free_((char *)lval);
return NULL;
}
rval = PopStr(ss, JSOP_SETNAME);
@ -2638,7 +2638,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
? "let (%s) (%s)"
: "let (%s) %s",
lval, rval);
cx->free((char *)lval);
cx->free_((char *)lval);
}
break;
@ -2701,7 +2701,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
if ((size_t)argc <= JS_ARRAY_LENGTH(smallv)) {
atomv = smallv;
} else {
atomv = (JSAtom **) cx->malloc(argc * sizeof(JSAtom *));
atomv = (JSAtom **) cx->malloc_(argc * sizeof(JSAtom *));
if (!atomv)
return NULL;
}
@ -2837,7 +2837,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
#undef LOCAL_ASSERT_OUT
enterblock_out:
if (atomv != smallv)
cx->free(atomv);
cx->free_(atomv);
if (!ok)
return NULL;
}
@ -3363,7 +3363,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
DECOMPILE_CODE(pc + oplen, len - oplen);
lval = JS_strdup(cx, POP_STR());
if (!lval) {
cx->free((void *)xval);
cx->free_((void *)xval);
return NULL;
}
pc += len;
@ -3374,8 +3374,8 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
rval = POP_STR();
todo = Sprint(&ss->sprinter, "%s ? %s : %s",
xval, lval, rval);
cx->free((void *)xval);
cx->free((void *)lval);
cx->free_((void *)xval);
cx->free_((void *)lval);
break;
default:
@ -3402,7 +3402,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
pc += len;
len = done - pc;
if (!Decompile(ss, pc, len, op)) {
cx->free((char *)lval);
cx->free_((char *)lval);
return NULL;
}
rval = POP_STR();
@ -3415,14 +3415,14 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
todo = Sprint(&ss->sprinter, "%s %s\n", lval, xval);
tail = Sprint(&ss->sprinter, "%*s%s",
jp->indent + 4, "", rval);
cx->free((char *)rval);
cx->free_((char *)rval);
}
if (tail < 0)
todo = -1;
} else {
todo = Sprint(&ss->sprinter, "%s %s %s", lval, xval, rval);
}
cx->free((char *)lval);
cx->free_((char *)lval);
break;
case JSOP_AND:
@ -3613,7 +3613,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
case JSOP_FUNAPPLY:
argc = GET_ARGC(pc);
argv = (char **)
cx->malloc((size_t)(argc + 1) * sizeof *argv);
cx->malloc_((size_t)(argc + 1) * sizeof *argv);
if (!argv)
return NULL;
@ -3672,8 +3672,8 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
ok = JS_FALSE;
for (i = 0; i <= argc; i++)
cx->free(argv[i]);
cx->free(argv);
cx->free_(argv[i]);
cx->free_(argv);
if (!ok)
return NULL;
break;
@ -4197,7 +4197,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
if (!rval)
return NULL;
todo = SprintCString(&ss->sprinter, rval);
cx->free((void *)rval);
cx->free_((void *)rval);
break;
}
#endif /* JS_HAS_GENERATOR_EXPRS */
@ -4269,7 +4269,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
ok = JS_TRUE;
} else {
table = (TableEntry *)
cx->malloc((size_t)n * sizeof *table);
cx->malloc_((size_t)n * sizeof *table);
if (!table)
return NULL;
for (i = j = 0; i < n; i++) {
@ -4289,13 +4289,13 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
pc2 += jmplen;
}
tmp = (TableEntry *)
cx->malloc((size_t)j * sizeof *table);
cx->malloc_((size_t)j * sizeof *table);
if (tmp) {
VOUCH_DOES_NOT_REQUIRE_STACK();
ok = js_MergeSort(table, (size_t)j, sizeof(TableEntry),
CompareOffsets, NULL, tmp,
JS_SORTING_GENERIC);
cx->free(tmp);
cx->free_(tmp);
} else {
ok = JS_FALSE;
}
@ -4305,7 +4305,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
ok = DecompileSwitch(ss, table, (uintN)j, pc, len, off,
JS_FALSE);
}
cx->free(table);
cx->free_(table);
if (!ok)
return NULL;
todo = -2;
@ -4331,7 +4331,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
pc2 += UINT16_LEN;
table = (TableEntry *)
cx->malloc((size_t)npairs * sizeof *table);
cx->malloc_((size_t)npairs * sizeof *table);
if (!table)
return NULL;
for (k = 0; k < npairs; k++) {
@ -4352,7 +4352,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
ok = DecompileSwitch(ss, table, (uintN)npairs, pc, len, off,
JS_FALSE);
cx->free(table);
cx->free_(table);
if (!ok)
return NULL;
todo = -2;
@ -4396,7 +4396,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
* and the distance to its statements in table[i].offset.
*/
table = (TableEntry *)
cx->malloc((size_t)ncases * sizeof *table);
cx->malloc_((size_t)ncases * sizeof *table);
if (!table)
return NULL;
pc2 = pc;
@ -4426,7 +4426,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
ok = DecompileSwitch(ss, table, (uintN)ncases, pc, len, off,
JS_TRUE);
cx->free(table);
cx->free_(table);
if (!ok)
return NULL;
todo = -2;
@ -4771,7 +4771,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
(*rval == '\0' ||
(SprintPut(&ss->sprinter, " ", 1) >= 0 &&
SprintCString(&ss->sprinter, rval)));
cx->free((char *)rval);
cx->free_((char *)rval);
if (!ok)
return NULL;
SprintPut(&ss->sprinter, "?>", 2);
@ -5119,7 +5119,7 @@ js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v_in,
* populated interpreter's stack with its current content.
*/
pcstack = (jsbytecode **)
cx->malloc(StackDepth(script) * sizeof *pcstack);
cx->malloc_(StackDepth(script) * sizeof *pcstack);
if (!pcstack)
return NULL;
intN pcdepth = ReconstructPCStack(cx, script, pc, pcstack);
@ -5161,7 +5161,7 @@ js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v_in,
}
release_pcstack:
cx->free(pcstack);
cx->free_(pcstack);
if (pcdepth < 0)
goto do_fallback;
}
@ -5294,7 +5294,7 @@ DecompileExpression(JSContext *cx, JSScript *script, JSFunction *fun,
}
pcstack = (jsbytecode **)
cx->malloc(StackDepth(script) * sizeof *pcstack);
cx->malloc_(StackDepth(script) * sizeof *pcstack);
if (!pcstack) {
name = NULL;
goto out;
@ -5321,7 +5321,7 @@ DecompileExpression(JSContext *cx, JSScript *script, JSFunction *fun,
}
out:
cx->free(pcstack);
cx->free_(pcstack);
return name;
}
@ -5403,7 +5403,7 @@ SimulateImacroCFG(JSContext *cx, JSScript *script,
jsbytecode** tmp_pcstack = NULL;
if (pcstack) {
nbytes = StackDepth(script) * sizeof *pcstack;
tmp_pcstack = (jsbytecode **) cx->malloc(nbytes);
tmp_pcstack = (jsbytecode **) cx->malloc_(nbytes);
if (!tmp_pcstack)
return -1;
memcpy(tmp_pcstack, pcstack, nbytes);
@ -5445,13 +5445,13 @@ SimulateImacroCFG(JSContext *cx, JSScript *script,
success:
if (tmp_pcstack) {
memcpy(pcstack, tmp_pcstack, nbytes);
cx->free(tmp_pcstack);
cx->free_(tmp_pcstack);
}
return pcdepth;
failure:
if (tmp_pcstack)
cx->free(tmp_pcstack);
cx->free_(tmp_pcstack);
return -1;
}
@ -5553,3 +5553,39 @@ ReconstructPCStack(JSContext *cx, JSScript *script, jsbytecode *target,
#undef LOCAL_ASSERT
#undef LOCAL_ASSERT_RV
namespace js {
bool
CallResultEscapes(jsbytecode *pc)
{
/*
* If we see any of these sequences, the result is unused:
* - call / pop
* - call / trace / pop
*
* If we see any of these sequences, the result is only tested for nullness:
* - call / ifeq
* - call / trace / ifeq
* - call / not / ifeq
* - call / trace / not / ifeq
*/
if (*pc != JSOP_CALL)
return true;
pc += JSOP_CALL_LENGTH;
if (*pc == JSOP_TRACE)
pc += JSOP_TRACE_LENGTH;
if (*pc == JSOP_POP)
return false;
if (*pc == JSOP_NOT)
pc += JSOP_NOT_LENGTH;
return (*pc != JSOP_IFEQ);
}
} // namespace js

View File

@ -516,6 +516,9 @@ SprintString(Sprinter *sp, JSString *str);
extern ptrdiff_t
Sprint(Sprinter *sp, const char *format, ...);
extern bool
CallResultEscapes(jsbytecode *pc);
}
#endif

View File

@ -9750,13 +9750,13 @@ js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc, bool inCond)
}
/* Allocate a new buffer and string descriptor for the result. */
jschar *chars = (jschar *) cx->malloc((length + 1) * sizeof(jschar));
jschar *chars = (jschar *) cx->malloc_((length + 1) * sizeof(jschar));
if (!chars)
return JS_FALSE;
chars[length] = 0;
JSString *str = js_NewString(cx, chars, length);
if (!str) {
cx->free(chars);
cx->free_(chars);
return JS_FALSE;
}

View File

@ -1016,11 +1016,11 @@ struct JSFunctionBoxQueue {
bool init(uint32 count) {
lengthMask = JS_BITMASK(JS_CeilingLog2(count));
vector = js_array_new<JSFunctionBox*>(length());
vector = js::OffTheBooks::array_new<JSFunctionBox*>(length());
return !!vector;
}
~JSFunctionBoxQueue() { js_array_delete(vector); }
~JSFunctionBoxQueue() { js::UnwantedForeground::array_delete(vector); }
void push(JSFunctionBox *funbox) {
if (!funbox->queued) {

View File

@ -52,6 +52,8 @@
#include "jspubtd.h"
#include "jsstr.h"
using namespace js;
/*
** Note: on some platforms va_list is defined as an array,
** and requires array notation.
@ -412,7 +414,7 @@ static int cvt_ws(SprintfState *ss, const jschar *ws, int width, int prec,
if (!s)
return -1; /* JSStuffFunc error indicator. */
result = cvt_s(ss, s, width, prec, flags);
js_free(s);
UnwantedForeground::free_(s);
} else {
result = cvt_s(ss, NULL, width, prec, flags);
}
@ -630,7 +632,7 @@ static struct NumArgState* BuildArgArray( const char *fmt, va_list ap, int* rv,
if( *rv < 0 ){
if( nas != nasArray )
js_free( nas );
UnwantedForeground::free_( nas );
return NULL;
}
@ -667,7 +669,7 @@ static struct NumArgState* BuildArgArray( const char *fmt, va_list ap, int* rv,
default:
if( nas != nasArray )
js_free( nas );
UnwantedForeground::free_( nas );
*rv = -1;
return NULL;
}
@ -756,7 +758,7 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap)
if( nas[i-1].type == TYPE_UNKNOWN ){
if( nas && ( nas != nasArray ) )
js_free( nas );
UnwantedForeground::free_( nas );
return -1;
}
@ -1037,7 +1039,7 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap)
rv = (*ss->stuff)(ss, "\0", 1);
if( nas && ( nas != nasArray ) ){
js_free( nas );
UnwantedForeground::free_( nas );
}
return rv;
@ -1098,9 +1100,9 @@ static int GrowStuff(SprintfState *ss, const char *sp, JSUint32 len)
/* Grow the buffer */
newlen = ss->maxlen + ((len > 32) ? len : 32);
if (ss->base) {
newbase = (char*) js_realloc(ss->base, newlen);
newbase = (char*) OffTheBooks::realloc_(ss->base, newlen);
} else {
newbase = (char*) js_malloc(newlen);
newbase = (char*) OffTheBooks::malloc_(newlen);
}
if (!newbase) {
/* Ran out of memory */
@ -1139,7 +1141,7 @@ JS_PUBLIC_API(char *) JS_smprintf(const char *fmt, ...)
*/
JS_PUBLIC_API(void) JS_smprintf_free(char *mem)
{
js_free(mem);
Foreground::free_(mem);
}
JS_PUBLIC_API(char *) JS_vsmprintf(const char *fmt, va_list ap)
@ -1154,7 +1156,7 @@ JS_PUBLIC_API(char *) JS_vsmprintf(const char *fmt, va_list ap)
rv = dosprintf(&ss, fmt, ap);
if (rv < 0) {
if (ss.base) {
js_free(ss.base);
Foreground::free_(ss.base);
}
return 0;
}
@ -1253,7 +1255,7 @@ JS_PUBLIC_API(char *) JS_vsprintf_append(char *last, const char *fmt, va_list ap
rv = dosprintf(&ss, fmt, ap);
if (rv < 0) {
if (ss.base) {
js_free(ss.base);
Foreground::free_(ss.base);
}
return 0;
}

View File

@ -61,7 +61,6 @@ PropertyCache::fill(JSContext *cx, JSObject *obj, uintN scopeIndex, uintN protoI
JS_ASSERT(this == &JS_PROPERTY_CACHE(cx));
JS_ASSERT(!cx->runtime->gcRunning);
JS_ASSERT_IF(adding, !obj->isCall());
if (js_IsPropertyCacheDisabled(cx)) {
PCMETER(disfills++);

View File

@ -80,13 +80,9 @@ PropertyTree::newShape(JSContext *cx)
static KidsHash *
HashChildren(Shape *kid1, Shape *kid2)
{
void *mem = js_malloc(sizeof(KidsHash));
if (!mem)
return NULL;
KidsHash *hash = new (mem) KidsHash();
if (!hash->init(2)) {
js_free(hash);
KidsHash *hash = OffTheBooks::new_<KidsHash>();
if (!hash || !hash->init(2)) {
Foreground::delete_(hash);
return NULL;
}
@ -344,7 +340,7 @@ Shape::finalize(JSContext *cx)
parent->removeChild(this);
if (kids.isHash())
js_delete(kids.toHash());
cx->delete_(kids.toHash());
}
freeTable(cx);

View File

@ -79,7 +79,7 @@ static void
resc_finalize(JSContext *cx, JSObject *obj)
{
RegExpStatics *res = static_cast<RegExpStatics *>(obj->getPrivate());
cx->destroy<RegExpStatics>(res);
cx->delete_(res);
}
static void
@ -588,7 +588,7 @@ EscapeNakedForwardSlashes(JSContext *cx, JSString *unescaped)
jschar *chars = newChars.extractRawBuffer();
JSString *escaped = js_NewString(cx, chars, len);
if (!escaped)
cx->free(chars);
cx->free_(chars);
return escaped;
}

View File

@ -70,7 +70,7 @@ regexp_statics_construct(JSContext *cx, JSObject *parent)
JSObject *obj = NewObject<WithProto::Given>(cx, &regexp_statics_class, NULL, parent);
if (!obj)
return NULL;
RegExpStatics *res = cx->create<RegExpStatics>();
RegExpStatics *res = cx->new_<RegExpStatics>();
if (!res)
return NULL;
obj->setPrivate(static_cast<void *>(res));
@ -117,6 +117,8 @@ class RegExp
#endif
{ }
JS_DECLARE_ALLOCATION_FRIENDS_FOR_PRIVATE_CONSTRUCTOR;
~RegExp() {
#if !ENABLE_YARR_JIT
if (compiled)
@ -124,9 +126,6 @@ class RegExp
#endif
}
/* Constructor/destructor are hidden; called by cx->create/destroy. */
friend struct ::JSContext;
bool compileHelper(JSContext *cx, JSLinearString &pattern);
bool compile(JSContext *cx);
static const uint32 allFlags = JSREG_FOLD | JSREG_GLOB | JSREG_MULTILINE | JSREG_STICKY;
@ -419,11 +418,11 @@ RegExp::create(JSContext *cx, JSString *source, uint32 flags)
JSLinearString *flatSource = source->ensureLinear(cx);
if (!flatSource)
return RetType(NULL);
RegExp *self = cx->create<RegExp>(flatSource, flags, cx->compartment);
RegExp *self = cx->new_<RegExp>(flatSource, flags, cx->compartment);
if (!self)
return RetType(NULL);
if (!self->compile(cx)) {
cx->destroy<RegExp>(self);
Foreground::delete_(self);
return RetType(NULL);
}
return RetType(self);
@ -576,7 +575,7 @@ RegExp::decref(JSContext *cx)
assertSameCompartment(cx, compartment);
#endif
if (--refCount == 0)
cx->destroy<RegExp>(this);
cx->delete_(this);
}
inline RegExp *

View File

@ -230,7 +230,7 @@ TokenStream::init(const jschar *base, size_t length, const char *fn, uintN ln, J
TokenStream::~TokenStream()
{
if (flags & TSF_OWNFILENAME)
cx->free((void *) filename);
cx->free_((void *) filename);
}
/* Use the fastest available getc. */
@ -475,7 +475,7 @@ TokenStream::reportCompileErrorNumberVA(JSParseNode *pn, uintN flags, uintN erro
if (report.lineno == lineno) {
size_t linelength = userbuf.findEOL() - linebase;
linechars = (jschar *)cx->malloc((linelength + 1) * sizeof(jschar));
linechars = (jschar *)cx->malloc_((linelength + 1) * sizeof(jschar));
if (!linechars) {
warning = false;
goto out;
@ -527,21 +527,21 @@ TokenStream::reportCompileErrorNumberVA(JSParseNode *pn, uintN flags, uintN erro
out:
if (linebytes)
cx->free(linebytes);
cx->free_(linebytes);
if (linechars)
cx->free(linechars);
cx->free_(linechars);
if (message)
cx->free(message);
cx->free_(message);
if (report.ucmessage)
cx->free((void *)report.ucmessage);
cx->free_((void *)report.ucmessage);
if (report.messageArgs) {
if (!(flags & JSREPORT_UC)) {
i = 0;
while (report.messageArgs[i])
cx->free((void *)report.messageArgs[i++]);
cx->free_((void *)report.messageArgs[i++]);
}
cx->free((void *)report.messageArgs);
cx->free_((void *)report.messageArgs);
}
return warning;
@ -706,7 +706,7 @@ TokenStream::getXMLEntity()
bytes = js_DeflateString(cx, bp + 1, (tb.end() - bp) - 1);
if (bytes) {
ReportCompileErrorNumber(cx, this, NULL, JSREPORT_ERROR, msg, bytes);
cx->free(bytes);
cx->free_(bytes);
}
return JS_FALSE;
}
@ -1662,7 +1662,7 @@ TokenStream::getTokenInternal()
if (c == EOF || c == '\n') {
if (i > 0) {
if (flags & TSF_OWNFILENAME)
cx->free((void *) filename);
cx->free_((void *) filename);
filename = JS_strdup(cx, filenameBuf);
if (!filename)
goto error;

View File

@ -157,10 +157,10 @@ PropertyTable::init(JSRuntime *rt, Shape *lastProp)
sizeLog2 = MIN_SIZE_LOG2;
/*
* Use rt->calloc for memory accounting and overpressure handling
* Use rt->calloc_ for memory accounting and overpressure handling
* without OOM reporting. See PropertyTable::change.
*/
entries = (Shape **) rt->calloc(JS_BIT(sizeLog2) * sizeof(Shape *));
entries = (Shape **) rt->calloc_(JS_BIT(sizeLog2) * sizeof(Shape *));
if (!entries) {
METER(tableAllocFails);
return false;
@ -187,10 +187,10 @@ bool
Shape::hashify(JSRuntime *rt)
{
JS_ASSERT(!hasTable());
void* mem = rt->malloc(sizeof(PropertyTable));
if (!mem)
PropertyTable *table = rt->new_<PropertyTable>(entryCount());
if (!table)
return false;
setTable(new(mem) PropertyTable(entryCount()));
setTable(table);
return getTable()->init(rt, this);
}
@ -323,17 +323,14 @@ PropertyTable::change(int log2Delta, JSContext *cx)
JS_ASSERT(entries);
/*
* Grow, shrink, or compress by changing this->entries. Here, we prefer
* cx->runtime->calloc to js_calloc, which on OOM waits for a background
* thread to finish sweeping and retry, if appropriate. Avoid cx->calloc
* so our caller can be in charge of whether to JS_ReportOutOfMemory.
* Grow, shrink, or compress by changing this->entries.
*/
oldlog2 = JS_DHASH_BITS - hashShift;
newlog2 = oldlog2 + log2Delta;
oldsize = JS_BIT(oldlog2);
newsize = JS_BIT(newlog2);
nbytes = PROPERTY_TABLE_NBYTES(newsize);
newTable = (Shape **) cx->runtime->calloc(nbytes);
newTable = (Shape **) cx->calloc_(nbytes);
if (!newTable) {
METER(tableAllocFails);
return false;
@ -358,12 +355,8 @@ PropertyTable::change(int log2Delta, JSContext *cx)
oldsize--;
}
/*
* Finally, free the old entries storage. Note that cx->runtime->free just
* calls js_free. Use js_free here to match PropertyTable::~PropertyTable,
* which cannot have a cx or rt parameter.
*/
js_free(oldTable);
/* Finally, free the old entries storage. */
cx->free_(oldTable);
return true;
}

View File

@ -242,7 +242,7 @@ struct PropertyTable {
}
~PropertyTable() {
js_free(entries);
js::UnwantedForeground::free_(entries);
}
/* By definition, hashShift = JS_DHASH_BITS - log2(capacity). */
@ -263,7 +263,7 @@ struct PropertyTable {
/*
* NB: init and change are fallible but do not report OOM, so callers can
* cope or ignore. They do however use JSRuntime's calloc method in order
* cope or ignore. They do however use JSRuntime's calloc_ method in order
* to update the malloc counter on success.
*/
bool init(JSRuntime *rt, js::Shape *lastProp);

View File

@ -57,7 +57,7 @@ inline void
js::Shape::freeTable(JSContext *cx)
{
if (hasTable()) {
cx->destroy(getTable());
cx->delete_(getTable());
setTable(NULL);
}
}
@ -71,7 +71,7 @@ JSObject::getEmptyShape(JSContext *cx, js::Class *aclasp,
if (!emptyShapes) {
emptyShapes = (js::EmptyShape**)
cx->calloc(sizeof(js::EmptyShape*) * js::gc::JS_FINALIZE_OBJECT_LIMIT);
cx->calloc_(sizeof(js::EmptyShape*) * js::gc::JS_FINALIZE_OBJECT_LIMIT);
if (!emptyShapes)
return NULL;
@ -81,7 +81,7 @@ JSObject::getEmptyShape(JSContext *cx, js::Class *aclasp,
*/
emptyShapes[0] = js::EmptyShape::create(cx, aclasp);
if (!emptyShapes[0]) {
cx->free(emptyShapes);
cx->free_(emptyShapes);
emptyShapes = NULL;
return NULL;
}

View File

@ -589,7 +589,7 @@ js_XDRScript(JSXDRState *xdr, JSScript **scriptp)
ok = JS_XDRBytes(xdr, (char *) code, length * sizeof(jsbytecode));
if (code != script->code)
cx->free(code);
cx->free_(code);
if (!ok)
goto error;
@ -604,7 +604,7 @@ js_XDRScript(JSXDRState *xdr, JSScript **scriptp)
if (!state->filenameSaved) {
const char *filename = state->filename;
filename = js_SaveScriptFilename(xdr->cx, filename);
xdr->cx->free((void *) state->filename);
xdr->cx->free_((void *) state->filename);
state->filename = filename;
state->filenameSaved = true;
if (!filename)
@ -803,13 +803,13 @@ typedef struct ScriptFilenameEntry {
static void *
js_alloc_table_space(void *priv, size_t size)
{
return js_malloc(size);
return OffTheBooks::malloc_(size);
}
static void
js_free_table_space(void *priv, void *item, size_t size)
{
js_free(item);
UnwantedForeground::free_(item);
}
static JSHashEntry *
@ -818,7 +818,7 @@ js_alloc_sftbl_entry(void *priv, const void *key)
size_t nbytes = offsetof(ScriptFilenameEntry, filename) +
strlen((const char *) key) + 1;
return (JSHashEntry *) js_malloc(JS_MAX(nbytes, sizeof(JSHashEntry)));
return (JSHashEntry *) OffTheBooks::malloc_(JS_MAX(nbytes, sizeof(JSHashEntry)));
}
static void
@ -826,7 +826,7 @@ js_free_sftbl_entry(void *priv, JSHashEntry *he, uintN flag)
{
if (flag != HT_FREE_ENTRY)
return;
js_free(he);
UnwantedForeground::free_(he);
}
static JSHashAllocOps sftbl_alloc_ops = {
@ -887,7 +887,7 @@ js_FreeRuntimeScriptState(JSRuntime *rt)
ScriptFilenamePrefix *sfp = (ScriptFilenamePrefix *)
rt->scriptFilenamePrefixes.next;
JS_REMOVE_LINK(&sfp->links);
js_free(sfp);
UnwantedForeground::free_(sfp);
}
FinishRuntimeScriptState(rt);
}
@ -950,7 +950,7 @@ SaveScriptFilename(JSRuntime *rt, const char *filename, uint32 flags)
if (!sfp) {
/* No such prefix: add one now. */
sfp = (ScriptFilenamePrefix *) js_malloc(sizeof(ScriptFilenamePrefix));
sfp = (ScriptFilenamePrefix *) rt->malloc_(sizeof(ScriptFilenamePrefix));
if (!sfp)
return NULL;
JS_INSERT_AFTER(&sfp->links, link);
@ -1229,7 +1229,7 @@ JSScript::NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natom
size += length * sizeof(jsbytecode) +
nsrcnotes * sizeof(jssrcnote);
script = (JSScript *) cx->malloc(size);
script = (JSScript *) cx->malloc_(size);
if (!script)
return NULL;
@ -1464,7 +1464,7 @@ JSScript::NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg)
memcpy(script->upvars()->vector, cg->upvarMap.vector,
cg->upvarList.count * sizeof(uint32));
cg->upvarList.clear();
cx->free(cg->upvarMap.vector);
cx->free_(cg->upvarMap.vector);
cg->upvarMap.vector = NULL;
}
@ -1626,7 +1626,7 @@ DestroyScript(JSContext *cx, JSScript *script)
#endif
JS_REMOVE_LINK(&script->links);
cx->free(script);
cx->free_(script);
}
void

View File

@ -216,8 +216,8 @@ AllocChars(JSContext *maybecx, size_t wholeCapacity)
JS_STATIC_ASSERT(JSString::MAX_LENGTH * sizeof(jschar) < UINT32_MAX);
size_t bytes = (wholeCapacity + 1) * sizeof(jschar);
if (maybecx)
return (jschar *)maybecx->malloc(bytes);
return (jschar *)js_malloc(bytes);
return (jschar *)maybecx->malloc_(bytes);
return (jschar *)OffTheBooks::malloc_(bytes);
}
JSFlatString *
@ -383,7 +383,7 @@ JSDependentString::undepend(JSContext *cx)
size_t n = length();
size_t size = (n + 1) * sizeof(jschar);
jschar *s = (jschar *) cx->malloc(size);
jschar *s = (jschar *) cx->malloc_(size);
if (!s)
return NULL;
@ -570,7 +570,7 @@ js_str_escape(JSContext *cx, uintN argc, Value *vp, Value *rval)
return JS_FALSE;
}
jschar *newchars = (jschar *) cx->malloc((newlength + 1) * sizeof(jschar));
jschar *newchars = (jschar *) cx->malloc_((newlength + 1) * sizeof(jschar));
if (!newchars)
return JS_FALSE;
size_t i, ni;
@ -600,7 +600,7 @@ js_str_escape(JSContext *cx, uintN argc, Value *vp, Value *rval)
JSString *retstr = js_NewString(cx, newchars, newlength);
if (!retstr) {
cx->free(newchars);
cx->free_(newchars);
return JS_FALSE;
}
rval->setString(retstr);
@ -626,7 +626,7 @@ str_unescape(JSContext *cx, uintN argc, Value *vp)
const jschar *chars = str->chars();
/* Don't bother allocating less space for the new string. */
jschar *newchars = (jschar *) cx->malloc((length + 1) * sizeof(jschar));
jschar *newchars = (jschar *) cx->malloc_((length + 1) * sizeof(jschar));
if (!newchars)
return false;
size_t ni = 0, i = 0;
@ -655,7 +655,7 @@ str_unescape(JSContext *cx, uintN argc, Value *vp)
JSString *retstr = js_NewString(cx, newchars, ni);
if (!retstr) {
cx->free(newchars);
cx->free_(newchars);
return JS_FALSE;
}
vp->setString(retstr);
@ -864,7 +864,7 @@ str_toSource(JSContext *cx, uintN argc, Value *vp)
return false;
size_t n = j + k + 2;
jschar *t = (jschar *) cx->malloc((n + 1) * sizeof(jschar));
jschar *t = (jschar *) cx->malloc_((n + 1) * sizeof(jschar));
if (!t)
return false;
@ -879,7 +879,7 @@ str_toSource(JSContext *cx, uintN argc, Value *vp)
str = js_NewString(cx, t, n);
if (!str) {
cx->free(t);
cx->free_(t);
return false;
}
vp->setString(str);
@ -978,7 +978,7 @@ js_toLowerCase(JSContext *cx, JSString *str)
if (!s)
return NULL;
jschar *news = (jschar *) cx->malloc((n + 1) * sizeof(jschar));
jschar *news = (jschar *) cx->malloc_((n + 1) * sizeof(jschar));
if (!news)
return NULL;
for (size_t i = 0; i < n; i++)
@ -986,7 +986,7 @@ js_toLowerCase(JSContext *cx, JSString *str)
news[n] = 0;
str = js_NewString(cx, news, n);
if (!str) {
cx->free(news);
cx->free_(news);
return NULL;
}
return str;
@ -1029,7 +1029,7 @@ js_toUpperCase(JSContext *cx, JSString *str)
const jschar *s = str->getChars(cx);
if (!s)
return NULL;
jschar *news = (jschar *) cx->malloc((n + 1) * sizeof(jschar));
jschar *news = (jschar *) cx->malloc_((n + 1) * sizeof(jschar));
if (!news)
return NULL;
for (size_t i = 0; i < n; i++)
@ -1037,7 +1037,7 @@ js_toUpperCase(JSContext *cx, JSString *str)
news[n] = 0;
str = js_NewString(cx, news, n);
if (!str) {
cx->free(news);
cx->free_(news);
return NULL;
}
return str;
@ -3094,7 +3094,7 @@ tagify(JSContext *cx, const char *begin, JSLinearString *param, const char *end,
return false;
}
jschar *tagbuf = (jschar *) cx->malloc((taglen + 1) * sizeof(jschar));
jschar *tagbuf = (jschar *) cx->malloc_((taglen + 1) * sizeof(jschar));
if (!tagbuf)
return false;
@ -3123,7 +3123,7 @@ tagify(JSContext *cx, const char *begin, JSLinearString *param, const char *end,
JSString *retstr = js_NewString(cx, tagbuf, taglen);
if (!retstr) {
js_free((char *)tagbuf);
Foreground::free_((char *)tagbuf);
return false;
}
vp->setString(retstr);
@ -3500,13 +3500,13 @@ str_fromCharCode(JSContext *cx, uintN argc, Value *vp)
}
argv[0].setInt32(code);
}
jschar *chars = (jschar *) cx->malloc((argc + 1) * sizeof(jschar));
jschar *chars = (jschar *) cx->malloc_((argc + 1) * sizeof(jschar));
if (!chars)
return JS_FALSE;
for (uintN i = 0; i < argc; i++) {
uint16_t code;
if (!ValueToUint16(cx, argv[i], &code)) {
cx->free(chars);
cx->free_(chars);
return JS_FALSE;
}
chars[i] = (jschar)code;
@ -3514,7 +3514,7 @@ str_fromCharCode(JSContext *cx, uintN argc, Value *vp)
chars[argc] = 0;
JSString *str = js_NewString(cx, chars, argc);
if (!str) {
cx->free(chars);
cx->free_(chars);
return JS_FALSE;
}
vp->setString(str);
@ -3646,9 +3646,9 @@ StringBuffer::finishString()
JS_ASSERT(capacity >= length);
if (capacity > sMinWasteSize && capacity - length > (length >> 2)) {
size_t bytes = sizeof(jschar) * (length + 1);
jschar *tmp = (jschar *)cx->realloc(buf, bytes);
jschar *tmp = (jschar *)cx->realloc_(buf, bytes);
if (!tmp) {
cx->free(buf);
cx->free_(buf);
return NULL;
}
buf = tmp;
@ -3656,7 +3656,7 @@ StringBuffer::finishString()
JSFixedString *str = js_NewString(cx, buf, length);
if (!str)
cx->free(buf);
cx->free_(buf);
return str;
}
@ -3722,14 +3722,14 @@ js_NewStringCopyN(JSContext *cx, const jschar *s, size_t n)
if (JSShortString::lengthFits(n))
return NewShortString(cx, s, n);
jschar *news = (jschar *) cx->malloc((n + 1) * sizeof(jschar));
jschar *news = (jschar *) cx->malloc_((n + 1) * sizeof(jschar));
if (!news)
return NULL;
js_strncpy(news, s, n);
news[n] = 0;
JSFixedString *str = js_NewString(cx, news, n);
if (!str)
cx->free(news);
cx->free_(news);
return str;
}
@ -3744,7 +3744,7 @@ js_NewStringCopyN(JSContext *cx, const char *s, size_t n)
return NULL;
JSFixedString *str = js_NewString(cx, chars, n);
if (!str)
cx->free(chars);
cx->free_(chars);
return str;
}
@ -3756,13 +3756,13 @@ js_NewStringCopyZ(JSContext *cx, const jschar *s)
return NewShortString(cx, s, n);
size_t m = (n + 1) * sizeof(jschar);
jschar *news = (jschar *) cx->malloc(m);
jschar *news = (jschar *) cx->malloc_(m);
if (!news)
return NULL;
memcpy(news, s, m);
JSFixedString *str = js_NewString(cx, news, n);
if (!str)
cx->free(news);
cx->free_(news);
return str;
}
@ -4034,7 +4034,7 @@ js_InflateString(JSContext *cx, const char *bytes, size_t *lengthp, bool useCESU
if (!js_InflateUTF8StringToBuffer(cx, bytes, nbytes, NULL, &nchars,
useCESU8))
goto bad;
chars = (jschar *) cx->malloc((nchars + 1) * sizeof (jschar));
chars = (jschar *) cx->malloc_((nchars + 1) * sizeof (jschar));
if (!chars)
goto bad;
#ifdef DEBUG
@ -4045,7 +4045,7 @@ js_InflateString(JSContext *cx, const char *bytes, size_t *lengthp, bool useCESU
JS_ASSERT(ok);
} else {
nchars = nbytes;
chars = (jschar *) cx->malloc((nchars + 1) * sizeof(jschar));
chars = (jschar *) cx->malloc_((nchars + 1) * sizeof(jschar));
if (!chars)
goto bad;
for (i = 0; i < nchars; i++)
@ -4080,7 +4080,7 @@ js_DeflateString(JSContext *cx, const jschar *chars, size_t nchars)
nbytes = js_GetDeflatedStringLength(cx, chars, nchars);
if (nbytes == (size_t) -1)
return NULL;
bytes = (char *) (cx ? cx->malloc(nbytes + 1) : js_malloc(nbytes + 1));
bytes = (char *) (cx ? cx->malloc_(nbytes + 1) : OffTheBooks::malloc_(nbytes + 1));
if (!bytes)
return NULL;
#ifdef DEBUG
@ -4090,7 +4090,7 @@ js_DeflateString(JSContext *cx, const jschar *chars, size_t nchars)
JS_ASSERT(ok);
} else {
nbytes = nchars;
bytes = (char *) (cx ? cx->malloc(nbytes + 1) : js_malloc(nbytes + 1));
bytes = (char *) (cx ? cx->malloc_(nbytes + 1) : OffTheBooks::malloc_(nbytes + 1));
if (!bytes)
return NULL;
for (i = 0; i < nbytes; i++)

View File

@ -469,7 +469,7 @@ JSString::finalize(JSContext *cx)
JS_RUNTIME_UNMETER(cx->runtime, liveDependentStrings);
} else if (isFlat()) {
cx->runtime->stringMemoryUsed -= length() * 2;
cx->free(const_cast<jschar *>(asFlat().chars()));
cx->free_(const_cast<jschar *>(asFlat().chars()));
} else {
JS_ASSERT(isRope());
}

View File

@ -46,13 +46,6 @@
#include <new>
#include <string.h>
/* Gross special case for Gecko, which defines malloc/calloc/free. */
#ifdef mozilla_mozalloc_macro_wrappers_h
# define JSSTL_UNDEFD_MOZALLOC_WRAPPERS
/* The "anti-header" */
# include "mozilla/mozalloc_undef_macro_wrappers.h"
#endif
namespace js {
/* JavaScript Template Library. */
@ -242,11 +235,11 @@ PointerRangeSize(T *begin, T *end)
/*
* Allocation policies. These model the concept:
* - public copy constructor, assignment, destructor
* - void *malloc(size_t)
* - void *malloc_(size_t)
* Responsible for OOM reporting on NULL return value.
* - void *realloc(size_t)
* - void *realloc_(size_t)
* Responsible for OOM reporting on NULL return value.
* - void free(void *)
* - void free_(void *)
* - reportAllocOverflow()
* Called on overflow before the container returns NULL.
*/
@ -255,9 +248,9 @@ PointerRangeSize(T *begin, T *end)
class SystemAllocPolicy
{
public:
void *malloc(size_t bytes) { return js_malloc(bytes); }
void *realloc(void *p, size_t bytes) { return js_realloc(p, bytes); }
void free(void *p) { js_free(p); }
void *malloc_(size_t bytes) { return js::OffTheBooks::malloc_(bytes); }
void *realloc_(void *p, size_t bytes) { return js::OffTheBooks::realloc_(p, bytes); }
void free_(void *p) { js::UnwantedForeground::free_(p); }
void reportAllocOverflow() const {}
};
@ -499,8 +492,4 @@ InitConst(const T &t)
} /* namespace js */
#ifdef JSSTL_UNDEFD_MOZALLOC_WRAPPERS
# include "mozilla/mozalloc_macro_wrappers.h"
#endif
#endif /* jstl_h_ */

View File

@ -148,13 +148,13 @@ using namespace js::tjit;
/* Implement embedder-specific nanojit members. */
/*
* Nanojit requires infallible allocations most of the time. We satisfy this
* by reserving some space in each allocator which is used as a fallback if
* js_calloc() fails. Ideallly this reserve space should be big enough to
* allow for all infallible requests made to the allocator until the next OOM
* check occurs, but it turns out that's impossible to guarantee (though it
* should be unlikely). So we abort if the reserve runs out; this is better
* than allowing memory errors to occur.
* Nanojit requires infallible allocations most of the time. We satisfy this by
* reserving some space in each allocator which is used as a fallback if
* rt->calloc_() fails. Ideally this reserve space should be big enough to allow
* for all infallible requests made to the allocator until the next OOM check
* occurs, but it turns out that's impossible to guarantee (though it should be
* unlikely). So we abort if the reserve runs out; this is better than
* allowing memory errors to occur.
*
* The space calculations are as follows... between OOM checks, each
* VMAllocator can do (ie. has been seen to do) the following maximum
@ -190,7 +190,7 @@ nanojit::Allocator::allocChunk(size_t nbytes, bool fallible)
* OOM check will still fail, which is what we want, and the success of
* request 2 makes it less likely that the reserve space will overflow.
*/
void *p = js_calloc(nbytes);
void *p = vma->mRt->calloc_(nbytes);
if (p) {
vma->mSize += nbytes;
} else {
@ -211,7 +211,7 @@ void
nanojit::Allocator::freeChunk(void *p) {
VMAllocator *vma = (VMAllocator*)this;
if (p < vma->mReserve || uintptr_t(p) >= vma->mReserveLimit)
js_free(p);
UnwantedForeground::free_(p);
}
void
@ -1084,7 +1084,8 @@ TraceRecorder::tprint(const char *format, LIns *ins1, LIns *ins2, LIns *ins3, LI
}
#endif
Tracker::Tracker()
Tracker::Tracker(JSContext *cx)
: cx(cx)
{
pagelist = NULL;
}
@ -1123,7 +1124,7 @@ struct Tracker::TrackerPage*
Tracker::addTrackerPage(const void* v)
{
jsuword base = getTrackerPageBase(v);
struct TrackerPage* p = (struct TrackerPage*) js_calloc(sizeof(*p));
struct TrackerPage* p = (struct TrackerPage*) cx->calloc_(sizeof(*p));
p->base = base;
p->next = pagelist;
pagelist = p;
@ -1136,7 +1137,7 @@ Tracker::clear()
while (pagelist) {
TrackerPage* p = pagelist;
pagelist = pagelist->next;
js_free(p);
cx->free_(p);
}
}
@ -2244,8 +2245,8 @@ TraceRecorder::TraceRecorder(JSContext* cx, TraceMonitor *tm,
lirbuf(new (tempAlloc()) LirBuffer(tempAlloc())),
mark(*traceMonitor->traceAlloc),
numSideExitsBefore(tree->sideExits.length()),
tracker(),
nativeFrameTracker(),
tracker(cx),
nativeFrameTracker(cx),
global_slots(NULL),
callDepth(anchor ? anchor->calldepth : 0),
atoms(FrameAtomBase(cx, cx->fp())),
@ -2480,9 +2481,7 @@ TraceRecorder::finishSuccessfully()
TraceMonitor* localtm = traceMonitor;
localtm->recorder = NULL;
/* We can't (easily) use js_delete() here because the destructor is private. */
this->~TraceRecorder();
js_free(this);
cx->delete_(this);
/* Catch OOM that occurred during recording. */
if (localtm->outOfMemory() || OverfullJITCache(localcx, localtm)) {
@ -2534,9 +2533,7 @@ TraceRecorder::finishAbort(const char* reason)
TraceMonitor* localtm = traceMonitor;
localtm->recorder = NULL;
/* We can't (easily) use js_delete() here because the destructor is private. */
this->~TraceRecorder();
js_free(this);
cx->delete_(this);
/* Catch OOM that occurred during recording. */
if (localtm->outOfMemory() || OverfullJITCache(localcx, localtm)) {
@ -4503,12 +4500,12 @@ TraceRecorder::compile()
#if defined DEBUG && !defined WIN32
/* Associate a filename and line number with the fragment. */
const char* filename = cx->fp()->script()->filename;
char* label = (char*)js_malloc((filename ? strlen(filename) : 7) + 16);
char* label = (char*) cx->malloc_((filename ? strlen(filename) : 7) + 16);
if (label) {
sprintf(label, "%s:%u", filename ? filename : "<stdin>",
js_FramePCToLineNumber(cx, cx->fp()));
lirbuf->printer->addrNameMap->addAddrRange(fragment, sizeof(Fragment), 0, label);
js_free(label);
cx->free_(label);
}
#endif
@ -5571,13 +5568,9 @@ TraceRecorder::startRecorder(JSContext* cx, TraceMonitor *tm, VMSideExit* anchor
JS_ASSERT(!tm->needFlush);
JS_ASSERT_IF(cx->fp()->hasImacropc(), f->root != f);
/* We can't (easily) use js_new() here because the constructor is private. */
void *memory = js_malloc(sizeof(TraceRecorder));
tm->recorder = memory
? new(memory) TraceRecorder(cx, tm, anchor, f, stackSlots, ngslots, typeMap,
tm->recorder = cx->new_<TraceRecorder>(cx, tm, anchor, f, stackSlots, ngslots, typeMap,
expectedInnerExit, outerScript, outerPC, outerArgc,
speculate)
: NULL;
speculate);
if (!tm->recorder || tm->outOfMemory() || OverfullJITCache(cx, tm)) {
ResetJIT(cx, tm, FR_OOM);
@ -7632,7 +7625,7 @@ SetMaxCodeCacheBytes(JSContext* cx, uint32 bytes)
}
bool
InitJIT(TraceMonitor *tm)
InitJIT(TraceMonitor *tm, JSRuntime* rt)
{
#if defined JS_JIT_SPEW
tm->profAlloc = NULL;
@ -7643,7 +7636,7 @@ InitJIT(TraceMonitor *tm)
}
/* Set up fragprofiling, if required. */
if (LogController.lcbits & LC_FragProfile) {
tm->profAlloc = js_new<VMAllocator>((char*)NULL, 0); /* no reserve needed in debug builds */
tm->profAlloc = rt->new_<VMAllocator>(rt, (char*)NULL, 0); /* no reserve needed in debug builds */
if (!tm->profAlloc)
goto error;
tm->profTab = new (*tm->profAlloc) FragStatsMap(*tm->profAlloc);
@ -7678,34 +7671,36 @@ InitJIT(TraceMonitor *tm)
did_we_check_processor_features = true;
}
#define CHECK_ALLOC(lhs, rhs) \
do { lhs = (rhs); if (!lhs) goto error; } while (0)
#define CHECK_NEW(lhs, type, args) \
do { lhs = rt->new_<type> args; if (!lhs) goto error; } while (0)
#define CHECK_MALLOC(lhs, conversion, size) \
do { lhs = (conversion)(rt->malloc_(size)); if (!lhs) goto error; } while (0)
CHECK_ALLOC(tm->oracle, js_new<Oracle>());
CHECK_NEW(tm->oracle, Oracle, ());
tm->profile = NULL;
CHECK_ALLOC(tm->recordAttempts, js_new<RecordAttemptMap>());
CHECK_NEW(tm->recordAttempts, RecordAttemptMap, ());
if (!tm->recordAttempts->init(PC_HASH_COUNT))
goto error;
CHECK_ALLOC(tm->loopProfiles, js_new<LoopProfileMap>());
CHECK_NEW(tm->loopProfiles, LoopProfileMap, ());
if (!tm->loopProfiles->init(PC_HASH_COUNT))
goto error;
tm->flushEpoch = 0;
char *dataReserve, *traceReserve, *tempReserve;
CHECK_ALLOC(dataReserve, (char *)js_malloc(DataReserveSize));
CHECK_ALLOC(traceReserve, (char *)js_malloc(TraceReserveSize));
CHECK_ALLOC(tempReserve, (char *)js_malloc(TempReserveSize));
CHECK_ALLOC(tm->dataAlloc, js_new<VMAllocator>(dataReserve, DataReserveSize));
CHECK_ALLOC(tm->traceAlloc, js_new<VMAllocator>(traceReserve, TraceReserveSize));
CHECK_ALLOC(tm->tempAlloc, js_new<VMAllocator>(tempReserve, TempReserveSize));
CHECK_ALLOC(tm->codeAlloc, js_new<CodeAlloc>());
CHECK_ALLOC(tm->frameCache, js_new<FrameInfoCache>(tm->dataAlloc));
CHECK_ALLOC(tm->storage, js_new<TraceNativeStorage>());
CHECK_ALLOC(tm->cachedTempTypeMap, js_new<TypeMap>((Allocator*)NULL, tm->oracle));
CHECK_MALLOC(dataReserve, char*, DataReserveSize);
CHECK_MALLOC(traceReserve, char*, TraceReserveSize);
CHECK_MALLOC(tempReserve, char*, TempReserveSize);
CHECK_NEW(tm->dataAlloc, VMAllocator, (rt, dataReserve, DataReserveSize));
CHECK_NEW(tm->traceAlloc, VMAllocator, (rt, traceReserve, TraceReserveSize));
CHECK_NEW(tm->tempAlloc, VMAllocator, (rt, tempReserve, TempReserveSize));
CHECK_NEW(tm->codeAlloc, CodeAlloc, ());
CHECK_NEW(tm->frameCache, FrameInfoCache, (tm->dataAlloc));
CHECK_NEW(tm->storage, TraceNativeStorage, ());
CHECK_NEW(tm->cachedTempTypeMap, TypeMap, ((Allocator*)NULL, tm->oracle));
tm->flush();
verbose_only( tm->branches = NULL; )
@ -7788,9 +7783,9 @@ FinishJIT(TraceMonitor *tm)
}
#endif
js_delete(tm->recordAttempts);
js_delete(tm->loopProfiles);
js_delete(tm->oracle);
Foreground::delete_(tm->recordAttempts);
Foreground::delete_(tm->loopProfiles);
Foreground::delete_(tm->oracle);
#ifdef DEBUG
// Recover profiling data from expiring Fragments, and display
@ -7810,7 +7805,7 @@ FinishJIT(TraceMonitor *tm)
if (tm->profTab)
FragProfiling_showResults(tm);
js_delete(tm->profAlloc);
Foreground::delete_(tm->profAlloc);
} else {
NanoAssert(!tm->profTab);
@ -7820,25 +7815,25 @@ FinishJIT(TraceMonitor *tm)
PodArrayZero(tm->vmfragments);
js_delete(tm->frameCache);
Foreground::delete_(tm->frameCache);
tm->frameCache = NULL;
js_delete(tm->codeAlloc);
Foreground::delete_(tm->codeAlloc);
tm->codeAlloc = NULL;
js_delete(tm->dataAlloc);
Foreground::delete_(tm->dataAlloc);
tm->dataAlloc = NULL;
js_delete(tm->traceAlloc);
Foreground::delete_(tm->traceAlloc);
tm->traceAlloc = NULL;
js_delete(tm->tempAlloc);
Foreground::delete_(tm->tempAlloc);
tm->tempAlloc = NULL;
js_delete(tm->storage);
Foreground::delete_(tm->storage);
tm->storage = NULL;
js_delete(tm->cachedTempTypeMap);
Foreground::delete_(tm->cachedTempTypeMap);
tm->cachedTempTypeMap = NULL;
}
@ -11440,37 +11435,15 @@ TraceRecorder::callNative(uintN argc, JSOp mode)
}
} else if (vp[2].isString() && mode == JSOP_CALL) {
if (native == js_regexp_exec) {
jsbytecode *pc = cx->regs->pc;
/*
* If we see any of these sequences, the result is unused:
* - call / pop
* - call / trace / pop
*
* If we see any of these sequences, the result is only tested for nullness:
* - call / ifeq
* - call / trace / ifeq
* - call / not / ifeq
* - call / trace / not / ifeq
*
* In either case, we replace the call to RegExp.exec() on the
* If the result of the call will be unused or only tested against
* nullness, we replace the call to RegExp.exec() on the
* stack with a call to RegExp.test() because "r.exec(s) !=
* null" is equivalent to "r.test(s)". This avoids building
* the result array, which can be expensive. This requires
* that RegExp.prototype.test() hasn't been changed; we check this.
*/
if (pc[0] == JSOP_CALL) {
if ((pc[JSOP_CALL_LENGTH] == JSOP_POP) ||
(pc[JSOP_CALL_LENGTH] == JSOP_TRACE &&
pc[JSOP_CALL_LENGTH + JSOP_TRACE_LENGTH] == JSOP_POP) ||
(pc[JSOP_CALL_LENGTH] == JSOP_IFEQ) ||
(pc[JSOP_CALL_LENGTH] == JSOP_TRACE &&
pc[JSOP_CALL_LENGTH + JSOP_TRACE_LENGTH] == JSOP_IFEQ) ||
(pc[JSOP_CALL_LENGTH] == JSOP_NOT &&
pc[JSOP_CALL_LENGTH + JSOP_NOT_LENGTH] == JSOP_IFEQ) ||
(pc[JSOP_CALL_LENGTH] == JSOP_TRACE &&
pc[JSOP_CALL_LENGTH + JSOP_TRACE_LENGTH] == JSOP_NOT &&
pc[JSOP_CALL_LENGTH + JSOP_TRACE_LENGTH + JSOP_NOT_LENGTH] == JSOP_IFEQ))
{
if (!CallResultEscapes(cx->regs->pc)) {
JSObject* proto;
jsid id = ATOM_TO_JSID(cx->runtime->atomState.testAtom);
/* Get RegExp.prototype.test() and check it hasn't been changed. */
@ -11485,7 +11458,6 @@ TraceRecorder::callNative(uintN argc, JSOp mode)
}
}
}
}
break;
case 2:
@ -16663,7 +16635,7 @@ StartTraceVisNative(JSContext *cx, uintN argc, jsval *vp)
if (!filename)
goto error;
ok = StartTraceVis(filename);
cx->free(filename);
cx->free_(filename);
} else {
ok = StartTraceVis();
}

View File

@ -76,7 +76,7 @@ public:
memcpy(tmp, _data, _len * sizeof(T));
_data = tmp;
} else {
_data = (T*)js_realloc(_data, _max * sizeof(T));
_data = (T*) js::OffTheBooks::realloc_(_data, _max * sizeof(T));
}
#if defined(DEBUG)
memset(&_data[_len], 0xcd, _max - _len);
@ -93,7 +93,7 @@ public:
~Queue() {
if (!alloc)
js_free(_data);
js::UnwantedForeground::free_(_data);
}
bool contains(T a) {
@ -199,12 +199,15 @@ class Tracker {
};
struct TrackerPage* pagelist;
/* Keep track of memory allocation. */
JSContext* cx;
jsuword getTrackerPageBase(const void* v) const;
jsuword getTrackerPageOffset(const void* v) const;
struct TrackerPage* findTrackerPage(const void* v) const;
struct TrackerPage* addTrackerPage(const void* v);
public:
Tracker();
Tracker(JSContext* cx);
~Tracker();
bool has(const void* v) const;
@ -407,15 +410,18 @@ struct VMSideExit : public nanojit::SideExit
class VMAllocator : public nanojit::Allocator
{
public:
VMAllocator(char* reserve, size_t reserveSize)
: mOutOfMemory(false), mSize(0), mReserve(reserve),
mReserveCurr(uintptr_t(reserve)), mReserveLimit(uintptr_t(reserve + reserveSize))
VMAllocator(JSRuntime *rt, char* reserve, size_t reserveSize)
: mOutOfMemory(false)
, mSize(0)
, mReserve(reserve)
, mReserveCurr(uintptr_t(reserve))
, mReserveLimit(uintptr_t(reserve + reserveSize))
, mRt(rt)
{}
~VMAllocator() {
js_free(mReserve);
js::UnwantedForeground::free_(mReserve);
}
size_t size() {
@ -472,6 +478,9 @@ public:
char* mReserve;
uintptr_t mReserveCurr;
uintptr_t mReserveLimit;
/* To keep track of allocation. */
JSRuntime* mRt;
};
struct FrameInfo {
@ -984,6 +993,8 @@ AbortProfiling(JSContext *cx);
class TraceRecorder
{
JS_DECLARE_ALLOCATION_FRIENDS_FOR_PRIVATE_CONSTRUCTOR;
/*************************************************************** Recording session constants */
/* The context in which recording started. */
@ -1691,7 +1702,7 @@ extern JS_REQUIRES_STACK TraceRecorder::AbortResult
AbortRecording(JSContext* cx, const char* reason);
extern bool
InitJIT(TraceMonitor *tm);
InitJIT(TraceMonitor *tm, JSRuntime *rt);
extern void
FinishJIT(TraceMonitor *tm);

View File

@ -123,7 +123,7 @@ ArrayBuffer::class_finalize(JSContext *cx, JSObject *obj)
ArrayBuffer *abuf = ArrayBuffer::fromJSObject(obj);
if (abuf) {
abuf->freeStorage(cx);
cx->destroy<ArrayBuffer>(abuf);
cx->delete_(abuf);
}
}
@ -161,12 +161,12 @@ ArrayBuffer::create(JSContext *cx, int32 nbytes)
return NULL;
}
ArrayBuffer *abuf = cx->create<ArrayBuffer>();
ArrayBuffer *abuf = cx->new_<ArrayBuffer>();
if (!abuf)
return NULL;
if (!abuf->allocateStorage(cx, nbytes)) {
cx->destroy<ArrayBuffer>(abuf);
Foreground::delete_(abuf);
return NULL;
}
@ -180,7 +180,7 @@ ArrayBuffer::allocateStorage(JSContext *cx, uint32 nbytes)
JS_ASSERT(data == 0);
if (nbytes) {
data = cx->calloc(nbytes);
data = cx->calloc_(nbytes);
if (!data)
return false;
}
@ -193,7 +193,7 @@ void
ArrayBuffer::freeStorage(JSContext *cx)
{
if (data) {
cx->free(data);
cx->free_(data);
#ifdef DEBUG
// the destructor asserts that data is 0 in debug builds
data = NULL;
@ -727,7 +727,7 @@ class TypedArrayTemplate
if (!obj)
return NULL;
ThisTypeArray *tarray = cx->create<ThisTypeArray>(bufobj, byteOffset, len);
ThisTypeArray *tarray = cx->new_<ThisTypeArray>(bufobj, byteOffset, len);
if (!tarray)
return NULL;
@ -832,7 +832,7 @@ class TypedArrayTemplate
{
ThisTypeArray *tarray = ThisTypeArray::fromJSObject(obj);
if (tarray)
cx->destroy<ThisTypeArray>(tarray);
cx->delete_(tarray);
}
/* subarray(start[, end]) */
@ -1264,7 +1264,7 @@ class TypedArrayTemplate
// We have to make a copy of the source array here, since
// there's overlap, and we have to convert types.
void *srcbuf = cx->malloc(tarray->byteLength);
void *srcbuf = cx->malloc_(tarray->byteLength);
if (!srcbuf)
return false;
memcpy(srcbuf, tarray->data, tarray->byteLength);
@ -1324,7 +1324,7 @@ class TypedArrayTemplate
break;
}
js_free(srcbuf);
UnwantedForeground::free_(srcbuf);
return true;
}

View File

@ -321,7 +321,7 @@ CallTree(void **bp)
return NULL;
/* Create a new callsite record. */
site = (JSCallsite *) js_malloc(sizeof(JSCallsite));
site = (JSCallsite *) OffTheBooks::malloc(sizeof(JSCallsite));
if (!site)
return NULL;

View File

@ -228,7 +228,11 @@ extern JS_PUBLIC_DATA(JSUint32) OOM_counter; /* data race, who cares. */
#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);
@ -251,94 +255,261 @@ static JS_INLINE void js_free(void* p) {
JS_END_EXTERN_C
#ifdef __cplusplus
/*
* User guide to memory memangement within SpiderMonkey:
*
* Quick tips:
*
* Allocation:
* - Prefer to allocate using JSContext:
* cx->{malloc_,realloc_,calloc_,new_,new_array}
*
* - If no JSContext is available, use a JSRuntime:
* rt->{malloc_,realloc_,calloc_,new_,new_array}
*
* - As a last resort, use unaccounted allocation ("OffTheBooks"):
* js::OffTheBooks::{malloc_,realloc_,calloc_,new_,new_array}
*
* 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.
* js_new()/js_array_new() should be used instead, and memory allocated with
* them should be deallocated with js_delete()/js_array_delete().
* (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.)
*
* If you have a class with a private constructor or destructor, you can
* make js_new/js_delete a friend. This can be fiddly, and the interaction of
* template functions, friend functions and namespaces can overwhelm even
* modern compilers. Manual inlining is probably easier.
* 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).
*
* (If you're wondering why we can't just use the 'nothrow' variant of
* new/new[], it's because we want to mediate *all* allocations within
* SpiderMonkey, to satisfy any embedders using JS_USE_CUSTOM_ALLOCATOR.)
* 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(t, parms) \
void *memory = js_malloc(sizeof(t)); \
#define JS_NEW_BODY(allocator, t, parms) \
void *memory = allocator(sizeof(t)); \
return memory ? new(memory) t parms : NULL;
template <class T>
JS_ALWAYS_INLINE T *js_new() {
JS_NEW_BODY(T, ())
/*
* 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_(const P1 &p1) {\
JS_NEW_BODY(ALLOCATOR, T, (p1))\
}\
\
template <class T, class P1, class P2>\
QUALIFIERS T *new_(const P1 &p1, const P2 &p2) {\
JS_NEW_BODY(ALLOCATOR, T, (p1, p2))\
}\
\
template <class T, class P1, class P2, class P3>\
QUALIFIERS T *new_(const P1 &p1, const P2 &p2, const P3 &p3) {\
JS_NEW_BODY(ALLOCATOR, T, (p1, p2, p3))\
}\
\
template <class T, class P1, class P2, class P3, class P4>\
QUALIFIERS T *new_(const P1 &p1, const P2 &p2, const P3 &p3, const 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_(const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4, const 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_(const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4, const P5 &p5, const 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_(const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4, const P5 &p5, const P6 &p6, const 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_(const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4, const P5 &p5, const P6 &p6, const P7 &p7, const 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_(const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4, const P5 &p5, const P6 &p6, const P7 &p7, const P8 &p8, const 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_(const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4, const P5 &p5, const P6 &p6, const P7 &p7, const P8 &p8, const P9 &p9, const 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_(const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4, const P5 &p5, const P6 &p6, const P7 &p7, const P8 &p8, const P9 &p9, const P10 &p10, const 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_(const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4, const P5 &p5, const P6 &p6, const P7 &p7, const P8 &p8, const P9 &p9, const P10 &p10, const P11 &p11, const 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);\
}\
}
template <class T, class P1>
JS_ALWAYS_INLINE T *js_new(const P1 &p1) {
JS_NEW_BODY(T, (p1))
/*
* 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);
}
template <class T, class P1, class P2>
JS_ALWAYS_INLINE T *js_new(const P1 &p1, const P2 &p2) {
JS_NEW_BODY(T, (p1, p2))
static JS_INLINE void* calloc_(size_t bytes) {
return ::js_calloc(bytes);
}
template <class T, class P1, class P2, class P3>
JS_ALWAYS_INLINE T *js_new(const P1 &p1, const P2 &p2, const P3 &p3) {
JS_NEW_BODY(T, (p1, p2, p3))
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);
}
template <class T, class P1, class P2, class P3, class P4>
JS_ALWAYS_INLINE T *js_new(const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4) {
JS_NEW_BODY(T, (p1, p2, p3, p4))
}
JS_DECLARE_DELETE_METHODS(::js_free, JS_ALWAYS_INLINE static)
};
/* ...add additional js_new()s as necessary... */
class UnwantedForeground : public Foreground {
};
#undef JS_NEW_BODY
} /* namespace js */
template <class T>
JS_ALWAYS_INLINE void js_delete(T *p) {
if (p) {
p->~T();
js_free(p);
}
}
/*
* 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
static const int JSMinAlignment = 8;
template <class T>
JS_ALWAYS_INLINE T *js_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 = js_malloc(numBytes);
if (!memory)
return NULL;
*(size_t *)memory = n;
memory = (void*)(uintptr_t(memory) + JSMinAlignment);
return new(memory) T[n];
}
template <class T>
JS_ALWAYS_INLINE void js_array_delete(T *p) {
if (p) {
void* p0 = (void *)(uintptr_t(p) - JSMinAlignment);
size_t n = *(size_t *)p0;
for (size_t i = 0; i < n; i++)
(p + i)->~T();
js_free(p0);
}
}
/**
* The following classes are designed to cause assertions to detect

View File

@ -50,12 +50,6 @@
#pragma warning(disable:4345)
#endif
/* Gross special case for Gecko, which defines malloc/calloc/free. */
#ifdef mozilla_mozalloc_macro_wrappers_h
# define JSVECTOR_UNDEFD_MOZALLOC_WRAPPERS
# include "mozilla/mozalloc_undef_macro_wrappers.h"
#endif
namespace js {
/*
@ -105,13 +99,13 @@ struct VectorImpl
*/
static inline bool growTo(Vector<T,N,AP> &v, size_t newcap) {
JS_ASSERT(!v.usingInlineStorage());
T *newbuf = reinterpret_cast<T *>(v.malloc(newcap * sizeof(T)));
T *newbuf = reinterpret_cast<T *>(v.malloc_(newcap * sizeof(T)));
if (!newbuf)
return false;
for (T *dst = newbuf, *src = v.beginNoCheck(); src != v.endNoCheck(); ++dst, ++src)
new(dst) T(*src);
VectorImpl::destroy(v.beginNoCheck(), v.endNoCheck());
v.free(v.mBegin);
v.free_(v.mBegin);
v.mBegin = newbuf;
/* v.mLength is unchanged. */
v.mCapacity = newcap;
@ -163,7 +157,7 @@ struct VectorImpl<T, N, AP, true>
static inline bool growTo(Vector<T,N,AP> &v, size_t newcap) {
JS_ASSERT(!v.usingInlineStorage());
size_t bytes = sizeof(T) * newcap;
T *newbuf = reinterpret_cast<T *>(v.realloc(v.mBegin, bytes));
T *newbuf = reinterpret_cast<T *>(v.realloc_(v.mBegin, bytes));
if (!newbuf)
return false;
v.mBegin = newbuf;
@ -451,7 +445,7 @@ Vector<T,N,AP>::~Vector()
REENTRANCY_GUARD_ET_AL;
Impl::destroy(beginNoCheck(), endNoCheck());
if (!usingInlineStorage())
this->free(beginNoCheck());
this->free_(beginNoCheck());
}
/*
@ -519,7 +513,7 @@ Vector<T,N,AP>::convertToHeapStorage(size_t lengthInc)
return false;
/* Allocate buffer. */
T *newBuf = reinterpret_cast<T *>(this->malloc(newCap * sizeof(T)));
T *newBuf = reinterpret_cast<T *>(this->malloc_(newCap * sizeof(T)));
if (!newBuf)
return false;
@ -801,7 +795,7 @@ Vector<T,N,AP>::extractRawBuffer()
{
T *ret;
if (usingInlineStorage()) {
ret = reinterpret_cast<T *>(this->malloc(mLength * sizeof(T)));
ret = reinterpret_cast<T *>(this->malloc_(mLength * sizeof(T)));
if (!ret)
return NULL;
Impl::copyConstruct(ret, beginNoCheck(), endNoCheck());
@ -829,7 +823,7 @@ Vector<T,N,AP>::replaceRawBuffer(T *p, size_t length)
/* Destroy what we have. */
Impl::destroy(beginNoCheck(), endNoCheck());
if (!usingInlineStorage())
this->free(beginNoCheck());
this->free_(beginNoCheck());
/* Take in the new buffer. */
if (length <= sInlineCapacity) {
@ -843,7 +837,7 @@ Vector<T,N,AP>::replaceRawBuffer(T *p, size_t length)
mCapacity = sInlineCapacity;
Impl::copyConstruct(mBegin, p, p + length);
Impl::destroy(p, p + length);
this->free(p);
this->free_(p);
} else {
mBegin = p;
mLength = length;
@ -860,8 +854,4 @@ Vector<T,N,AP>::replaceRawBuffer(T *p, size_t length)
#pragma warning(pop)
#endif
#ifdef JSVECTOR_UNDEFD_MOZALLOC_WRAPPERS
# include "mozilla/mozalloc_macro_wrappers.h"
#endif
#endif /* jsvector_h_ */

View File

@ -95,7 +95,7 @@ typedef struct JSXDRMemState {
if (MEM_LIMIT(xdr) && \
MEM_COUNT(xdr) + bytes > MEM_LIMIT(xdr)) { \
uint32 limit_ = JS_ROUNDUP(MEM_COUNT(xdr) + bytes, MEM_BLOCK);\
void *data_ = (xdr)->cx->realloc(MEM_BASE(xdr), limit_); \
void *data_ = (xdr)->cx->realloc_(MEM_BASE(xdr), limit_); \
if (!data_) \
return 0; \
MEM_BASE(xdr) = (char *) data_; \
@ -221,7 +221,7 @@ mem_tell(JSXDRState *xdr)
static void
mem_finalize(JSXDRState *xdr)
{
xdr->cx->free(MEM_BASE(xdr));
xdr->cx->free_(MEM_BASE(xdr));
}
static JSXDROps xdrmem_ops = {
@ -245,13 +245,13 @@ JS_XDRInitBase(JSXDRState *xdr, JSXDRMode mode, JSContext *cx)
JS_PUBLIC_API(JSXDRState *)
JS_XDRNewMem(JSContext *cx, JSXDRMode mode)
{
JSXDRState *xdr = (JSXDRState *) cx->malloc(sizeof(JSXDRMemState));
JSXDRState *xdr = (JSXDRState *) cx->malloc_(sizeof(JSXDRMemState));
if (!xdr)
return NULL;
JS_XDRInitBase(xdr, mode, cx);
if (mode == JSXDR_ENCODE) {
if (!(MEM_BASE(xdr) = (char *) cx->malloc(MEM_BLOCK))) {
cx->free(xdr);
if (!(MEM_BASE(xdr) = (char *) cx->malloc_(MEM_BLOCK))) {
cx->free_(xdr);
return NULL;
}
} else {
@ -305,11 +305,11 @@ JS_XDRDestroy(JSXDRState *xdr)
JSContext *cx = xdr->cx;
xdr->ops->finalize(xdr);
if (xdr->registry) {
cx->free(xdr->registry);
cx->free_(xdr->registry);
if (xdr->reghash)
JS_DHashTableDestroy((JSDHashTable *) xdr->reghash);
}
cx->free(xdr);
cx->free_(xdr);
}
JS_PUBLIC_API(JSBool)
@ -387,12 +387,12 @@ JS_XDRCString(JSXDRState *xdr, char **sp)
len = strlen(*sp);
JS_XDRUint32(xdr, &len);
if (xdr->mode == JSXDR_DECODE) {
if (!(*sp = (char *) xdr->cx->malloc(len + 1)))
if (!(*sp = (char *) xdr->cx->malloc_(len + 1)))
return JS_FALSE;
}
if (!JS_XDRBytes(xdr, *sp, len)) {
if (xdr->mode == JSXDR_DECODE)
xdr->cx->free(*sp);
xdr->cx->free_(*sp);
return JS_FALSE;
}
if (xdr->mode == JSXDR_DECODE) {
@ -457,7 +457,7 @@ JS_XDRString(JSXDRState *xdr, JSString **strp)
*strp = js_NewString(xdr->cx, chars, len);
if (!*strp) {
xdr->cx->free(chars);
xdr->cx->free_(chars);
return false;
}
}
@ -696,7 +696,7 @@ XDRScriptState::~XDRScriptState()
{
xdr->state = NULL;
if (xdr->mode == JSXDR_DECODE && filename && !filenameSaved)
xdr->cx->free((void *)filename);
xdr->cx->free_((void *)filename);
}
JS_PUBLIC_API(JSBool)
@ -768,7 +768,7 @@ JS_XDRRegisterClass(JSXDRState *xdr, JSClass *clasp, uint32 *idp)
if (numclasses == maxclasses) {
maxclasses = (maxclasses == 0) ? CLASS_REGISTRY_MIN : maxclasses << 1;
registry = (JSClass **)
xdr->cx->realloc(xdr->registry, maxclasses * sizeof(JSClass *));
xdr->cx->realloc_(xdr->registry, maxclasses * sizeof(JSClass *));
if (!registry)
return JS_FALSE;
xdr->registry = registry;

View File

@ -429,20 +429,20 @@ ConvertQNameToString(JSContext *cx, JSObject *obj)
if (obj->getClass() == &js_AttributeNameClass) {
JS::Anchor<JSString *> anchor(str);
size_t length = str->length();
jschar *chars = (jschar *) cx->malloc((length + 2) * sizeof(jschar));
jschar *chars = (jschar *) cx->malloc_((length + 2) * sizeof(jschar));
if (!chars)
return JS_FALSE;
*chars = '@';
const jschar *strChars = str->getChars(cx);
if (!strChars) {
cx->free(chars);
cx->free_(chars);
return NULL;
}
js_strncpy(chars + 1, strChars, length);
chars[++length] = 0;
str = js_NewString(cx, chars, length);
if (!str) {
cx->free(chars);
cx->free_(chars);
return NULL;
}
}
@ -889,9 +889,9 @@ JSXMLArray::setCapacity(JSContext *cx, uint32 newCapacity)
/* We could let realloc(p, 0) free this, but purify gets confused. */
if (vector) {
if (cx)
cx->free(vector);
cx->free_(vector);
else
js_free(vector);
Foreground::free_(vector);
}
vector = NULL;
} else {
@ -901,7 +901,7 @@ JSXMLArray::setCapacity(JSContext *cx, uint32 newCapacity)
#if JS_BITS_PER_WORD == 32
(size_t)newCapacity > ~(size_t)0 / sizeof(void *) ||
#endif
!(tmp = (void **) js_realloc(vector, newCapacity * sizeof(void *)))) {
!(tmp = (void **) OffTheBooks::realloc_(vector, newCapacity * sizeof(void *)))) {
if (cx)
JS_ReportOutOfMemory(cx);
return false;
@ -924,7 +924,7 @@ JSXMLArray::trim()
void
JSXMLArray::finish(JSContext *cx)
{
cx->free(vector);
cx->free_(vector);
while (JSXMLArrayCursor *cursor = cursors)
cursor->disconnect();
@ -988,7 +988,7 @@ XMLArrayAddMember(JSContext *cx, JSXMLArray *array, uint32 index, void *elt)
(size_t)capacity > ~(size_t)0 / sizeof(void *) ||
#endif
!(vector = (void **)
js_realloc(array->vector, capacity * sizeof(void *)))) {
cx->realloc_(array->vector, capacity * sizeof(void *)))) {
JS_ReportOutOfMemory(cx);
return JS_FALSE;
}
@ -1069,10 +1069,10 @@ XMLArrayTruncate(JSContext *cx, JSXMLArray *array, uint32 length)
if (length == 0) {
if (array->vector)
cx->free(array->vector);
cx->free_(array->vector);
vector = NULL;
} else {
vector = (void **) js_realloc(array->vector, length * sizeof(void *));
vector = (void **) cx->realloc_(array->vector, length * sizeof(void *));
if (!vector)
return;
}
@ -1707,7 +1707,7 @@ ParseXMLSource(JSContext *cx, JSString *src)
length = constrlen(prefix) + urilen + constrlen(middle) + srclen +
constrlen(suffix);
chars = (jschar *) cx->malloc((length + 1) * sizeof(jschar));
chars = (jschar *) cx->malloc_((length + 1) * sizeof(jschar));
if (!chars)
return NULL;
@ -1722,7 +1722,7 @@ ParseXMLSource(JSContext *cx, JSString *src)
offset += dstlen;
srcp = src->getChars(cx);
if (!srcp) {
cx->free(chars);
cx->free_(chars);
return NULL;
}
js_strncpy(chars + offset, srcp, srclen);
@ -1757,7 +1757,7 @@ ParseXMLSource(JSContext *cx, JSString *src)
if (parser.init(chars, length, filename, lineno, cx->findVersion())) {
JSObject *scopeChain = GetScopeChain(cx);
if (!scopeChain) {
cx->free(chars);
cx->free_(chars);
return NULL;
}
JSParseNode *pn = parser.parseXMLText(scopeChain, false);
@ -1770,7 +1770,7 @@ ParseXMLSource(JSContext *cx, JSString *src)
}
}
cx->free(chars);
cx->free_(chars);
return xml;
#undef constrlen
@ -2292,7 +2292,7 @@ GeneratePrefix(JSContext *cx, JSLinearString *uri, JSXMLArray *decls)
if (STARTS_WITH_XML(cp, length) || !IsXMLName(cp, length)) {
newlength = length + 2 + (size_t) log10((double) decls->length);
bp = (jschar *)
cx->malloc((newlength + 1) * sizeof(jschar));
cx->malloc_((newlength + 1) * sizeof(jschar));
if (!bp)
return NULL;
@ -2317,7 +2317,7 @@ GeneratePrefix(JSContext *cx, JSLinearString *uri, JSXMLArray *decls)
if (bp == cp) {
newlength = length + 2 + (size_t) log10((double) n);
bp = (jschar *)
cx->malloc((newlength + 1) * sizeof(jschar));
cx->malloc_((newlength + 1) * sizeof(jschar));
if (!bp)
return NULL;
js_strncpy(bp, cp, length);
@ -2344,7 +2344,7 @@ GeneratePrefix(JSContext *cx, JSLinearString *uri, JSXMLArray *decls)
} else {
prefix = js_NewString(cx, bp, newlength);
if (!prefix)
cx->free(bp);
cx->free_(bp);
}
return prefix;
}
@ -4886,7 +4886,7 @@ xml_enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, Value *statep,
if (length == 0) {
statep->setInt32(0);
} else {
cursor = cx->create<JSXMLArrayCursor>(&xml->xml_kids);
cursor = cx->new_<JSXMLArrayCursor>(&xml->xml_kids);
if (!cursor)
return JS_FALSE;
statep->setPrivate(cursor);
@ -4912,7 +4912,7 @@ xml_enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, Value *statep,
if (!statep->isInt32(0)) {
cursor = (JSXMLArrayCursor *) statep->toPrivate();
if (cursor)
cx->destroy(cursor);
cx->delete_(cursor);
}
statep->setNull();
break;
@ -7334,7 +7334,7 @@ js_AddAttributePart(JSContext *cx, JSBool isName, JSString *str, JSString *str2)
return NULL;
size_t newlen = (isName) ? len + 1 + len2 : len + 2 + len2 + 1;
jschar *newchars = (jschar *) cx->malloc((newlen+1) * sizeof(jschar));
jschar *newchars = (jschar *) cx->malloc_((newlen+1) * sizeof(jschar));
if (!newchars)
return NULL;
@ -7582,7 +7582,7 @@ xmlfilter_finalize(JSContext *cx, JSObject *obj)
if (!filter)
return;
cx->destroy(filter);
cx->delete_(filter);
}
Class js_XMLFilterClass = {
@ -7652,7 +7652,7 @@ js_StepXMLListFilter(JSContext *cx, JSBool initialized)
* Init all filter fields before setPrivate exposes it to
* xmlfilter_trace or xmlfilter_finalize.
*/
filter = cx->create<JSXMLFilter>(list, &list->xml_kids);
filter = cx->new_<JSXMLFilter>(list, &list->xml_kids);
if (!filter)
return JS_FALSE;
filterobj->setPrivate(filter);

View File

@ -187,7 +187,7 @@ mjit::Compiler::performCompilation(JITScript **jitp)
return Compile_Error;
}
jumpMap = (Label *)cx->malloc(sizeof(Label) * script->length);
jumpMap = (Label *)cx->malloc_(sizeof(Label) * script->length);
if (!jumpMap) {
js_ReportOutOfMemory(cx);
return Compile_Error;
@ -234,8 +234,8 @@ mjit::Compiler::performCompilation(JITScript **jitp)
mjit::Compiler::~Compiler()
{
cx->free(jumpMap);
cx->free(savedTraps);
cx->free_(jumpMap);
cx->free_(savedTraps);
}
CompileStatus JS_NEVER_INLINE
@ -260,7 +260,7 @@ mjit::TryCompile(JSContext *cx, JSStackFrame *fp)
bool
mjit::Compiler::loadOldTraps(const Vector<CallSite> &sites)
{
savedTraps = (bool *)cx->calloc(sizeof(bool) * script->length);
savedTraps = (bool *)cx->calloc_(sizeof(bool) * script->length);
if (!savedTraps)
return false;
@ -447,7 +447,7 @@ mjit::Compiler::finishThisUp(JITScript **jitp)
#endif
sizeof(CallSite) * callSites.length();
uint8 *cursor = (uint8 *)cx->calloc(totalBytes);
uint8 *cursor = (uint8 *)cx->calloc_(totalBytes);
if (!cursor) {
execPool->release();
js_ReportOutOfMemory(cx);

View File

@ -62,7 +62,7 @@ FrameState::FrameState(JSContext *cx, JSScript *script, JSFunction *fun, Assembl
FrameState::~FrameState()
{
cx->free(entries);
cx->free_(entries);
}
bool
@ -86,7 +86,7 @@ FrameState::init()
? 0
: sizeof(JSPackedBool) * nargs); // closedArgs[]
uint8 *cursor = (uint8 *)cx->calloc(totalBytes);
uint8 *cursor = (uint8 *)cx->calloc_(totalBytes);
if (!cursor)
return false;

View File

@ -54,13 +54,13 @@ ImmutableSync::ImmutableSync(JSContext *cx, const FrameState &frame)
ImmutableSync::~ImmutableSync()
{
cx->free(entries);
cx->free_(entries);
}
bool
ImmutableSync::init(uint32 nentries)
{
entries = (SyncEntry *)cx->calloc(sizeof(SyncEntry) * nentries);
entries = (SyncEntry *)cx->calloc_(sizeof(SyncEntry) * nentries);
return !!entries;
}

View File

@ -623,7 +623,7 @@ JS_STATIC_ASSERT(JSVAL_PAYLOAD_MASK == 0x00007FFFFFFFFFFFLL);
bool
JaegerCompartment::Initialize()
{
execAlloc_ = js_new<JSC::ExecutableAllocator>();
execAlloc_ = js::OffTheBooks::new_<JSC::ExecutableAllocator>();
if (!execAlloc_)
return false;
@ -647,7 +647,7 @@ void
JaegerCompartment::Finish()
{
TrampolineCompiler::release(&trampolines);
js_delete(execAlloc_);
Foreground::delete_(execAlloc_);
#ifdef JS_METHODJIT_PROFILE_STUBS
FILE *fp = fopen("/tmp/stub-profiling", "wt");
# define OPDEF(op,val,name,image,length,nuses,ndefs,prec,format) \
@ -909,7 +909,7 @@ mjit::ReleaseScriptCode(JSContext *cx, JSScript *script)
cx->runtime->mjitMemoryUsed -= jscr->scriptDataSize() + jscr->mainCodeSize();
jscr->~JITScript();
cx->free(jscr);
cx->free_(jscr);
script->jitNormal = NULL;
script->jitArityCheckNormal = NULL;
}
@ -918,7 +918,7 @@ mjit::ReleaseScriptCode(JSContext *cx, JSScript *script)
cx->runtime->mjitMemoryUsed -= jscr->scriptDataSize() + jscr->mainCodeSize();
jscr->~JITScript();
cx->free(jscr);
cx->free_(jscr);
script->jitCtor = NULL;
script->jitArityCheckCtor = NULL;
}

View File

@ -233,9 +233,9 @@ class CompilerAllocPolicy : public ContextAllocPolicy
: ContextAllocPolicy(cx), oomFlag(oomFlag) {}
CompilerAllocPolicy(JSContext *cx, Compiler &compiler);
void *malloc(size_t bytes) { return checkAlloc(ContextAllocPolicy::malloc(bytes)); }
void *realloc(void *p, size_t bytes) {
return checkAlloc(ContextAllocPolicy::realloc(p, bytes));
void *malloc_(size_t bytes) { return checkAlloc(ContextAllocPolicy::malloc_(bytes)); }
void *realloc_(void *p, size_t bytes) {
return checkAlloc(ContextAllocPolicy::realloc_(p, bytes));
}
};

View File

@ -900,7 +900,17 @@ class CallCompiler : public BaseCompiler
else
masm.storeArg(1, argcReg.reg());
masm.storeArg(0, cxReg);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, fun->u.n.native), false);
js::Native native = fun->u.n.native;
/*
* Call RegExp.test instead of exec if the result will not be used or
* will only be used to test for existence.
*/
if (native == js_regexp_exec && !CallResultEscapes(f.regs.pc))
native = js_regexp_test;
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, native), false);
Jump hasException = masm.branchTest32(Assembler::Zero, Registers::ReturnReg,
Registers::ReturnReg);

View File

@ -560,6 +560,7 @@ class SetPropCompiler : public PICStubCompiler
* populate the slot to satisfy the method invariant (in case we
* hit an early return below).
*/
id = js_CheckForStringIndex(id);
const Shape *shape =
obj->putProperty(cx, id, getter, clasp->setProperty,
SHAPE_INVALID_SLOT, JSPROP_ENUMERATE, flags, 0);
@ -2135,7 +2136,7 @@ GetElementIC::attachGetProp(JSContext *cx, JSObject *obj, const Value &v, jsid i
JaegerSpew(JSpew_PICs, "generated %s stub at %p for atom 0x%x (\"%s\") shape 0x%x (%s: %d)\n",
js_CodeName[op], cs.executableAddress(), id, chars, holder->shape(),
cx->fp()->script()->filename, js_FramePCToLineNumber(cx, cx->fp()));
cx->free(chars);
cx->free_(chars);
#endif
// Update the inline guards, if needed.

View File

@ -157,7 +157,7 @@ class BasePolyIC : public BaseIC {
~BasePolyIC() {
releasePools();
if (areMultiplePools())
js_delete(multiplePools());
Foreground::delete_(multiplePools());
}
void reset() {
@ -192,11 +192,11 @@ class BasePolyIC : public BaseIC {
if (isOnePool()) {
JSC::ExecutablePool *oldPool = u.execPool;
JS_ASSERT(!isTagged(oldPool));
ExecPoolVector *execPools = js_new<ExecPoolVector>(SystemAllocPolicy());
ExecPoolVector *execPools = cx->new_<ExecPoolVector>(SystemAllocPolicy());
if (!execPools)
return false;
if (!execPools->append(oldPool) || !execPools->append(pool)) {
js_delete(execPools);
Foreground::delete_(execPools);
return false;
}
u.taggedExecPools = tag(execPools);

View File

@ -63,7 +63,7 @@ pm_construct(JSContext* cx, uintN argc, jsval* vp)
if (!JS_FreezeObject(cx, obj))
return JS_FALSE;
PerfMeasurement* p = js_new<PerfMeasurement>(PerfMeasurement::EventMask(mask));
PerfMeasurement* p = cx->new_<PerfMeasurement>(PerfMeasurement::EventMask(mask));
if (!p) {
JS_ReportOutOfMemory(cx);
return JS_FALSE;
@ -77,7 +77,7 @@ pm_construct(JSContext* cx, uintN argc, jsval* vp)
static void
pm_finalize(JSContext* cx, JSObject* obj)
{
js_delete((PerfMeasurement*) JS_GetPrivate(cx, obj));
cx->delete_((PerfMeasurement*) JS_GetPrivate(cx, obj));
}
// Property access

View File

@ -39,6 +39,8 @@
#include "jsperf.h"
#include "jsutil.h"
using namespace js;
/* This variant of nsIPerfMeasurement uses the perf_event interface
* added in Linux 2.6.31. We key compilation of this file off the
* existence of <linux/perf_event.h>.
@ -265,7 +267,7 @@ namespace JS {
#define initCtr(flag) ((eventsMeasured & flag) ? 0 : -1)
PerfMeasurement::PerfMeasurement(PerfMeasurement::EventMask toMeasure)
: impl(js_new<Impl>()),
: impl(OffTheBooks::new_<Impl>()),
eventsMeasured(impl ? static_cast<Impl*>(impl)->init(toMeasure)
: EventMask(0)),
cpu_cycles(initCtr(CPU_CYCLES)),
@ -286,7 +288,7 @@ PerfMeasurement::PerfMeasurement(PerfMeasurement::EventMask toMeasure)
PerfMeasurement::~PerfMeasurement()
{
js_delete(static_cast<Impl*>(impl));
js::Foreground::delete_(static_cast<Impl*>(impl));
}
void

View File

@ -56,7 +56,7 @@ LIBS = $(NSPR_LIBS) $(EDITLINE_LIBS) $(DEPTH)/$(LIB_PREFIX)js_static.$(LIB_
LOCAL_INCLUDES += -I$(topsrcdir) -I..
FAIL_ON_WARNINGS = 1
#FAIL_ON_WARNINGS = 1
ifdef _MSC_VER
ifdef WINCE

View File

@ -99,3 +99,4 @@ script regress-635195.js
script regress-636394.js
script regress-636364.js
script regress-640075.js
script regress-643222.js

View File

@ -0,0 +1,12 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
/* This shouldn't trigger an assertion. */
(function () {
eval("var x=delete(x)")
})();
reportCompare(0, 0, "ok");

View File

@ -76,7 +76,9 @@ class XULInfoTester:
elif out in ('false\n', 'false\r\n'):
ans = False
else:
raise Exception("Failed to test XUL condition '%s'"%cond)
raise Exception(("Failed to test XUL condition %r;"
+ " output was %r, stderr was %r")
% (cond, out, err))
self.cache[cond] = ans
return ans

View File

@ -2588,9 +2588,7 @@ JSRegExp* jsRegExpCompile(const UChar* pattern, int patternLength,
return returnError(ERR16, error);
size_t size = length + sizeof(JSRegExp);
// FIXME: bug 574459 -- no NULL check
JSRegExp* re = reinterpret_cast<JSRegExp*>(js_array_new<char>(size));
JSRegExp* re = reinterpret_cast<JSRegExp*>(js::OffTheBooks::array_new<char>(size));
if (!re)
return returnError(ERR13, error);
@ -2645,7 +2643,7 @@ JSRegExp* jsRegExpCompile(const UChar* pattern, int patternLength,
/* Failed to compile, or error while post-processing */
if (errorcode != ERR0) {
js_array_delete(reinterpret_cast<char*>(re));
js::Foreground::array_delete(reinterpret_cast<char*>(re));
return returnError(errorcode, error);
}
@ -2700,5 +2698,5 @@ JSRegExp* jsRegExpCompile(const UChar* pattern, int patternLength,
void jsRegExpFree(JSRegExp* re)
{
js_array_delete(reinterpret_cast<char*>(re));
js::Foreground::array_delete(reinterpret_cast<char*>(re));
}

View File

@ -394,7 +394,7 @@ struct MatchStack {
if (canUseStackBufferForNextFrame())
return currentFrame + 1;
// FIXME: bug 574459 -- no NULL check
MatchFrame *frame = js_new<MatchFrame>();
MatchFrame *frame = js::OffTheBooks::new_<MatchFrame>();
frame->init(regExpPool);
return frame;
}
@ -417,7 +417,7 @@ struct MatchStack {
MatchFrame* oldFrame = currentFrame;
currentFrame = currentFrame->previousFrame;
if (size > numFramesOnStack)
js_delete(oldFrame);
js::Foreground::delete_(oldFrame);
size--;
}

View File

@ -2630,7 +2630,7 @@ static const char _wordcharData[65536] = {
CharacterClass* digitsCreate()
{
// FIXME: bug 574459 -- no NULL check
CharacterClass* characterClass = js_new<CharacterClass>((CharacterClassTable*)NULL);
CharacterClass* characterClass = js::OffTheBooks::new_<CharacterClass>((CharacterClassTable*)NULL);
characterClass->m_ranges.append(CharacterRange(0x30, 0x39));
return characterClass;
}
@ -2638,7 +2638,7 @@ CharacterClass* digitsCreate()
CharacterClass* nondigitsCreate()
{
// FIXME: bug 574459 -- no NULL check
CharacterClass* characterClass = js_new<CharacterClass>((CharacterClassTable*)NULL);
CharacterClass* characterClass = js::OffTheBooks::new_<CharacterClass>((CharacterClassTable*)NULL);
characterClass->m_ranges.append(CharacterRange(0x00, 0x2f));
characterClass->m_ranges.append(CharacterRange(0x3a, 0x7f));
characterClass->m_rangesUnicode.append(CharacterRange(0x0080, 0xffff));
@ -2648,7 +2648,7 @@ CharacterClass* nondigitsCreate()
CharacterClass* newlineCreate()
{
// FIXME: bug 574459 -- no NULL check
CharacterClass* characterClass = js_new<CharacterClass>((CharacterClassTable*)NULL);
CharacterClass* characterClass = js::OffTheBooks::new_<CharacterClass>((CharacterClassTable*)NULL);
characterClass->m_matches.append(0x0a);
characterClass->m_matches.append(0x0d);
characterClass->m_matchesUnicode.append(0x2028);
@ -2659,7 +2659,7 @@ CharacterClass* newlineCreate()
CharacterClass* spacesCreate()
{
// FIXME: bug 574459 -- no NULL check
CharacterClass* characterClass = js_new<CharacterClass>(CharacterClassTable::create(_spacesData, false));
CharacterClass* characterClass = js::OffTheBooks::new_<CharacterClass>(CharacterClassTable::create(_spacesData, false));
characterClass->m_ranges.append(CharacterRange(0x09, 0x0d));
characterClass->m_matches.append(0x20);
characterClass->m_matchesUnicode.append(0x00a0);
@ -2677,7 +2677,7 @@ CharacterClass* spacesCreate()
CharacterClass* nonspacesCreate()
{
// FIXME: bug 574459 -- no NULL check
CharacterClass* characterClass = js_new<CharacterClass>(CharacterClassTable::create(_spacesData, true));
CharacterClass* characterClass = js::OffTheBooks::new_<CharacterClass>(CharacterClassTable::create(_spacesData, true));
characterClass->m_ranges.append(CharacterRange(0x00, 0x08));
characterClass->m_ranges.append(CharacterRange(0x0e, 0x1f));
characterClass->m_ranges.append(CharacterRange(0x21, 0x7f));
@ -2696,7 +2696,7 @@ CharacterClass* nonspacesCreate()
CharacterClass* nonwordcharCreate()
{
// FIXME: bug 574459 -- no NULL check
CharacterClass* characterClass = js_new<CharacterClass>(CharacterClassTable::create(_wordcharData, true));
CharacterClass* characterClass = js::OffTheBooks::new_<CharacterClass>(CharacterClassTable::create(_wordcharData, true));
characterClass->m_ranges.append(CharacterRange(0x00, 0x2f));
characterClass->m_ranges.append(CharacterRange(0x3a, 0x40));
characterClass->m_ranges.append(CharacterRange(0x5b, 0x5e));
@ -2709,7 +2709,7 @@ CharacterClass* nonwordcharCreate()
CharacterClass* wordcharCreate()
{
// FIXME: bug 574459 -- no NULL check
CharacterClass* characterClass = js_new<CharacterClass>(CharacterClassTable::create(_wordcharData, false));
CharacterClass* characterClass = js::OffTheBooks::new_<CharacterClass>(CharacterClassTable::create(_wordcharData, false));
characterClass->m_ranges.append(CharacterRange(0x30, 0x39));
characterClass->m_ranges.append(CharacterRange(0x41, 0x5a));
characterClass->m_matches.append(0x5f);

View File

@ -140,7 +140,7 @@ public:
CharacterClass* charClass()
{
// FIXME: bug 574459 -- no NULL check
CharacterClass* characterClass = js_new<CharacterClass>((CharacterClassTable*)NULL);
CharacterClass* characterClass = js::OffTheBooks::new_<CharacterClass>((CharacterClassTable*)NULL);
characterClass->m_matches.append(m_matches);
characterClass->m_ranges.append(m_ranges);
@ -346,7 +346,7 @@ public:
m_pattern.m_numSubpatterns++;
// FIXME: bug 574459 -- no NULL check
PatternDisjunction* parenthesesDisjunction = js_new<PatternDisjunction>(m_alternative);
PatternDisjunction* parenthesesDisjunction = js::OffTheBooks::new_<PatternDisjunction>(m_alternative);
m_pattern.m_disjunctions.append(parenthesesDisjunction);
m_alternative->m_terms.append(PatternTerm(PatternTerm::TypeParenthesesSubpattern, subpatternId, parenthesesDisjunction, capture));
m_alternative = parenthesesDisjunction->addNewAlternative();
@ -355,7 +355,7 @@ public:
void atomParentheticalAssertionBegin(bool invert = false)
{
// FIXME: bug 574459 -- no NULL check
PatternDisjunction* parenthesesDisjunction = js_new<PatternDisjunction>(m_alternative);
PatternDisjunction* parenthesesDisjunction = js::OffTheBooks::new_<PatternDisjunction>(m_alternative);
m_pattern.m_disjunctions.append(parenthesesDisjunction);
m_alternative->m_terms.append(PatternTerm(PatternTerm::TypeParentheticalAssertion, m_pattern.m_numSubpatterns + 1, parenthesesDisjunction, invert));
m_alternative = parenthesesDisjunction->addNewAlternative();
@ -401,7 +401,7 @@ public:
PatternDisjunction* copyDisjunction(PatternDisjunction* disjunction)
{
// FIXME: bug 574459 -- no NULL check
PatternDisjunction* newDisjunction = js_new<PatternDisjunction>();
PatternDisjunction* newDisjunction = js::OffTheBooks::new_<PatternDisjunction>();
newDisjunction->m_parent = disjunction->m_parent;
for (unsigned alt = 0; alt < disjunction->m_alternatives.length(); ++alt) {
@ -472,7 +472,7 @@ public:
void regexBegin()
{
// FIXME: bug 574459 -- no NULL check
m_pattern.m_body = js_new<PatternDisjunction>();
m_pattern.m_body = js::OffTheBooks::new_<PatternDisjunction>();
m_alternative = m_pattern.m_body->addNewAlternative();
m_pattern.m_disjunctions.append(m_pattern.m_body);
}

View File

@ -60,6 +60,9 @@ struct CharacterRange {
* between character classes, so it's refcounted.
*/
struct CharacterClassTable {
JS_DECLARE_ALLOCATION_FRIENDS_FOR_PRIVATE_CONSTRUCTOR;
const char* m_table;
bool m_inverted;
jsrefcount m_refcount;
@ -69,13 +72,11 @@ struct CharacterClassTable {
{
// FIXME: bug 574459 -- no NULL checks done by any of the callers, all
// of which are in RegExpJitTables.h.
/* We can't (easily) use js_new() here because the constructor is private. */
void *memory = js_malloc(sizeof(CharacterClassTable));
return memory ? new(memory) CharacterClassTable(table, inverted) : NULL;
return js::OffTheBooks::new_<CharacterClassTable>(table, inverted);
}
void incref() { JS_ATOMIC_INCREMENT(&m_refcount); }
void decref() { if (JS_ATOMIC_DECREMENT(&m_refcount) == 0) js_delete(this); }
void decref() { if (JS_ATOMIC_DECREMENT(&m_refcount) == 0) js::Foreground::delete_(this); }
private:
CharacterClassTable(const char* table, bool inverted)
@ -230,6 +231,9 @@ struct PatternTerm {
};
struct PatternAlternative {
JS_DECLARE_ALLOCATION_FRIENDS_FOR_PRIVATE_CONSTRUCTOR;
PatternAlternative(PatternDisjunction* disjunction)
: m_parent(disjunction)
, m_onceThrough(false)
@ -275,10 +279,13 @@ static inline void
deleteAllValues(js::Vector<T*,N,AP> &vector)
{
for (T** t = vector.begin(); t < vector.end(); ++t)
js_delete(*t);
js::Foreground::delete_(*t);
}
struct PatternDisjunction {
JS_DECLARE_ALLOCATION_FRIENDS_FOR_PRIVATE_CONSTRUCTOR;
PatternDisjunction(PatternAlternative* parent = 0)
: m_parent(parent)
, m_hasFixedSize(false)
@ -293,7 +300,7 @@ struct PatternDisjunction {
PatternAlternative* addNewAlternative()
{
// FIXME: bug 574459 -- no NULL check
PatternAlternative* alternative = js_new<PatternAlternative>(this);
PatternAlternative* alternative = js::OffTheBooks::new_<PatternAlternative>(this);
m_alternatives.append(alternative);
return alternative;
}

View File

@ -107,9 +107,9 @@ private:
class SystemAllocPolicy {
public:
void *malloc(size_t bytes) { return ::malloc(bytes); }
void *realloc(void *p, size_t bytes) { return ::realloc(p, bytes); }
void free(void *p) { ::free(p); }
void *malloc_(size_t bytes) { return ::malloc(bytes); }
void *realloc_(void *p, size_t bytes) { return ::realloc(p, bytes); }
void free_(void *p) { ::free(p); }
void reportAllocOverflow() const {}
};

View File

@ -545,7 +545,7 @@ XRE_API(MessageLoop*,
XRE_GetIOMessageLoop, ())
struct JSContext;
struct JSString;
class JSString;
XRE_API(bool,
XRE_SendTestShellCommand, (JSContext* aCx,