michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #if !defined(JSGC_USE_EXACT_ROOTING) michael@0: michael@0: #include "jsobj.h" michael@0: michael@0: #include "jsapi-tests/tests.h" michael@0: #include "vm/String.h" michael@0: michael@0: BEGIN_TEST(testConservativeGC) michael@0: { michael@0: JS::RootedValue v2(cx); michael@0: EVAL("({foo: 'bar'});", &v2); michael@0: CHECK(v2.isObject()); michael@0: char objCopy[sizeof(JSObject)]; michael@0: js_memcpy(&objCopy, JSVAL_TO_OBJECT(v2), sizeof(JSObject)); michael@0: michael@0: JS::RootedValue v3(cx); michael@0: EVAL("String(Math.PI);", &v3); michael@0: CHECK(JSVAL_IS_STRING(v3)); michael@0: char strCopy[sizeof(JSString)]; michael@0: js_memcpy(&strCopy, JSVAL_TO_STRING(v3), sizeof(JSString)); michael@0: michael@0: JS::RootedValue tmp(cx); michael@0: EVAL("({foo2: 'bar2'});", &tmp); michael@0: CHECK(tmp.isObject()); michael@0: JS::RootedObject obj2(cx, JSVAL_TO_OBJECT(tmp)); michael@0: char obj2Copy[sizeof(JSObject)]; michael@0: js_memcpy(&obj2Copy, obj2, sizeof(JSObject)); michael@0: michael@0: EVAL("String(Math.sqrt(3));", &tmp); michael@0: CHECK(JSVAL_IS_STRING(tmp)); michael@0: JS::RootedString str2(cx, JSVAL_TO_STRING(tmp)); michael@0: char str2Copy[sizeof(JSString)]; michael@0: js_memcpy(&str2Copy, str2, sizeof(JSString)); michael@0: michael@0: tmp = JSVAL_NULL; michael@0: michael@0: JS_GC(rt); michael@0: michael@0: EVAL("var a = [];\n" michael@0: "for (var i = 0; i != 10000; ++i) {\n" michael@0: "a.push(i + 0.1, [1, 2], String(Math.sqrt(i)), {a: i});\n" michael@0: "}", &tmp); michael@0: michael@0: JS_GC(rt); michael@0: michael@0: checkObjectFields((JSObject *)objCopy, JSVAL_TO_OBJECT(v2)); michael@0: CHECK(!memcmp(strCopy, JSVAL_TO_STRING(v3), sizeof(strCopy))); michael@0: michael@0: checkObjectFields((JSObject *)obj2Copy, obj2); michael@0: CHECK(!memcmp(str2Copy, str2, sizeof(str2Copy))); michael@0: michael@0: return true; michael@0: } michael@0: michael@0: bool checkObjectFields(JSObject *savedCopy, JSObject *obj) michael@0: { michael@0: /* Ignore fields which are unstable across GCs. */ michael@0: CHECK(savedCopy->lastProperty() == obj->lastProperty()); michael@0: return true; michael@0: } michael@0: michael@0: END_TEST(testConservativeGC) michael@0: michael@0: BEGIN_TEST(testDerivedValues) michael@0: { michael@0: JSString *str = JS_NewStringCopyZ(cx, "once upon a midnight dreary"); michael@0: JS::Anchor str_anchor(str); michael@0: static const jschar expected[] = { 'o', 'n', 'c', 'e' }; michael@0: const jschar *ch = JS_GetStringCharsZ(cx, str); michael@0: str = nullptr; michael@0: michael@0: /* Do a lot of allocation and collection. */ michael@0: for (int i = 0; i < 3; i++) { michael@0: for (int j = 0; j < 1000; j++) michael@0: JS_NewStringCopyZ(cx, "as I pondered weak and weary"); michael@0: JS_GC(rt); michael@0: } michael@0: michael@0: CHECK(!memcmp(ch, expected, sizeof(expected))); michael@0: return true; michael@0: } michael@0: END_TEST(testDerivedValues) michael@0: michael@0: #endif /* !defined(JSGC_USE_EXACT_ROOTING) */